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
