TSa wrote:
>>   role Collection[\$types] {
>>        has Seq[$types] @.members;
>>   }
> This is a little wrapper that ensures that collections have got
> a @.members sequence of arbitrary type. This immediately raises
> the question how Seq is defined.
> [...and later...]
> Are you sure that the underlying Seq type handles the one and
> two parameter forms you've used so far?

Ah, yes, a notable omission.  I understood a Seq as a list with
individual types for each element, which are applied positionally.  The
superclass for things like Pair.

Here's a quick mock-up of what I mean:

   role Seq[ \$types ] {
       submethod COMPOSE {  # a la BUILD for classes
           loop( my $i = 0; $i < $types.elems; $i++ ) {
               # assumption: "self" here is the class
               # we're composing to, and "has" is a class
               # method that works a little like Moose
               self.has( $i++ => (isa => $types.[$i]) );
           }
       }
       my subset MySeqIndex of Int
           where { 0 <= $_ < $types.elems };

       method post_circimfix:<[ ]>( $element: MySeqIndex ) {
           $?SELF.$element;
       }
   }

Seq is certainly interesting for various reasons.  One is that it is a
parametric role that takes an arbitrary set of parameters.  In fact,
it's possible that the type arguments are something more complicated
than a list (making for some very "interesting" Seq types); the above
represents a capture, but the above code treats it was a simple list.

>>   role Set[::T = Item] does Collection[T] where {
>>       all(.members) =:= one(.members);
>>   };
> 
> Nice usage of junctions! But how is the assertion of
> uniqueness transported into methods that handle adding
> of new values?

I haven't defined any mutable state yet; it's still "pure".

I'd expect mutability to be a different role, and a set of primitives
that work on this level by returning a new set with the changes made.
In fact the mutable Set could re-use those primitives, by just having a
Set as a member (that 'handles' the Set role methods), and automatically
changing that member each time a change is made, to point to the new Set
with the new contents.

Which all sounds very inefficient and scary until you realise what
happens inside generative GC VMs that support STM.

>>   role Mapping[::K = Item, ::V = Item] does Collection[Pair[K,V]] {
>>       all(.members).does(Pair) and
>>       all(.members).key =:= one(.members).key;
>>   }
> 
> I guess this is a typo and you wanted a where clause. The first
> assertion of the members doing the Pair role should be guaranteed
> by using Pair as the type argument when instantiating the Collection
> role.

Well spotted; yes, that is superfluous.

>>   role Hash[Str ::K, ::V = Item] does Mapping[K, V]
> 
> Will the Str assertion not be too specific for non-string hashes?

Another assumption I make here is that there is a basic type "Hash",
which as its name suggests, is all about hashing strings, and that the
more general form is called "Mapping" where any object can be the
source, not just Str subtypes.

Thanks for your other nitpicks and comments - much appreciated!

Sam.


>>       where { all(.members).key == one(.members).key }
>>   {
>>       method post_circumfix:<{ }> (K $key) of V|Undefined {
> 
> Nice union type as return type. But isn't the type name Undef?
> 
>>           my $seq = first { .key == $key } &.members;
> 
> Wasn't that @.members?
> 
>>           $seq ?? $seq.value :: undef;
> 
> Ternary is spelled ?? !! now.
> 
> 
>>       }
>>   }
>>  
>>   role ArrayItem[::V = Item] does Seq[Int, V] {
>>       method index of Int { .[0] }
>>       method value of Item { .[1] }
>>   };
> 
> Here we see the two parameter version of Seq at work.
> 
> 
>>   role Array of Collection[ArrayItem]
>>       where { all(.members).index == one(.members).index }
>>   {
>>       method post_circumfix:<[ ]> (Int $index) of Item {
>>           my $seq = first { .index == $index } &.members;
> 
> Is this first there a grep-like function? Shouldn't it then
> read 'first { .index == $index }, @.members'?
> 
> 
>>           $seq ?? $seq.value :: undef;
>>       }
>>   }
>>
>> I'll take the feedback I get, and try to make a set of Perl 6 classes in
>> the pugs project that look and feel just like regular Perl 6 hash/arrays
>> but are expressed in more elementary particles.
> 
> This might be very useful in future debates about these types. But
> I think everything hinges on the basic Seq type.
> 
> 
> Regards, TSa.

Reply via email to