Moose's type-checking philosophy seems to be that we should specify type constraints at the level of an attribute, and check types at the point when an attribute is set. It does not normally check other method parameters. It can, though, e.g. with MooseX::Params::Validate or Moops. This can create performance problems with type-checking aggregates. If you have a large array, and you set a ArrayRefInt to point to it, the constraint must now check every element in the array. What if we had a class that contained an arrayref, and had a type constraint, and methods on that class that are used to add elements would check the type constraint for the added elements? Then when we passed one of these objects in as a Moose attribute, the check for the types of all elements would be constant time.
package TypedArray; use Moose; has type => ( is => 'ro', isa => 'Moose::Meta::TypeConstraint', required => 1 ); has elems => ( is => 'ro', isa => ArrayRef, default => sub { [] }, ); sub BUILD { my $self = shift; $self->type->assert_valid($_) for @{$self->elems}; } sub elems_push { my $self = shift; $self->type->assert_valid($_) for @_; push @{$self->elems}, @_; } ... more methods and operator overloads ...
Using overloaded operators, we could make them work much like built-in arrays. To create a new one, you would write, e.g.:
TypedArray->new(type => Int, elems => [4, 8, -7])
It would be nice to have a shorthand syntax to create them. We could use BUILDARGS to simplify it to:
TypedArray->new(Int, 4, 8, -7)
but it would be nice to get rid of even the `new`. We could make a function, e.g.:
typedArray Int, 4, 8, -7
Then we could define a parameterizable type constraint called TypedArrayOf:
subtype TypedArrayOf as Parameterizable['TypedArray', 'Moose::Meta::TypeConstraint' +], where { my ($typed_array, $type) = @_; $typed_array->type->is_a_type_of($type) }, message { my ($typed_array, $type) = @_; return "expected TypedArrayOf[$type], found TypedArrayOf[@ +{[$typed_array->type]}]" };
Unfortunately, we could not use the class name for the type constraint, because this is not a class constraint, and we do not want to conflict with the class constraint. So I chose a compromise by appending the word 'Of' to the name. Instead of having a single TypedArray class, another option would be to create a new class on the fly for each possible type parameter. We could use a parameterized role to build them, using Class::MOP to generate the new classes on demand. Then TypedArray would become a function, taking a single parameter that is an arrayref with the contained type. E.g.,
TypedArray[Int]
would look up the Int type in a global cache, and if not found, would generate a new TypedArray class, parameterized on Int. That class would constrain all elements to be Ints. This could get expensive if we end up creating a lot of classes. What do folks think of the naming here? Can we be more succinct? More consistent? How can we avoid naming conflicts between 1) the class without a type parameter, 2) the class with a type parameter, 3) a constructor function without a type paramter, 4) a constructor function with a type parameter, 5) the type constraint without a parameter, 6) the type constraint with a parameter. What is the most "Moosey" approach?

In reply to Naming question by QSeep

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.