1) Complex types for sub parameters: The above would imply that a sub can tell the difference between an C<Array of int> vs an C<Array of str>, thank goodness. That also implies that you can use arbitrarily complex types, and still get the same type checking:
sub foo ( %pet is Hash of Array of Array of Hash of Array of Cat ) {...}
Yes/No?
Yes.
2) Multimethod dispatch: The text would seem to _IMPLY_ that you can perform multimethod dispatch based on complex types, but it isn't actually stated anywhere AFAICT. e.g.
multi foo (@a is Array of str) {...} multi foo (@a is Array of int) {...}
... is it legal,
Yes.
> and DWYM?
Depends WYM. ;-)
3) The edge point between explicitly typed and explicitly non-typed variables: If you pass an "untyped" array (or list?) to an explicitly typed array parameter, is the "untyped" array considered a unique case, or will it fail?
multi foo (@a is Array of int) {...}
my int @a = baz(); # is Array of int my @b = baz(); # is Array of Scalar
foo(@a); # @a is typed correctly, so OK foo(@b); # @b is not explicitly typed as C<int>; OK or FAIL?
Fails.
Because:
not (Array of Scalar).isa(Array of int)
Which in turn is because:
not Scalar.isa(int)
To extend the example a little further:
multi Aoi (int @a) {...} multi AoS (Scalar @a) {...} multi AoI (Int @a) {...}
my int @aoi; my @aoS; my Int @aoI;
Aoi(aoi); # Okay because int.isa(int) Aoi(aoS); # Fails because !Scalar.isa(int) Aoi(aoI); # Fails because !Int.isa(int)
AoS(aoi); # Fails because !int.isa(Scalar) AoS(aoS); # Okay because Scalar.isa(Scalar) AoS(aoI); # Okay because Int.isa(Scalar)
AoI(aoi); # Fails because !int.isa(Int) AoI(aoS); # Fails because !Scalar.isa(Int) AoI(aoI); # Okay because Int.isa(Int)
Damian