<disclaimer> Sorry for the last thread. Please let it die off. Let me restart the thread, asking the same question, hopefully making more sense this time. I promise to write in concrete Perl6, instead of Compiler Speak. Really. </disclaimer>
In Synopsis 6 version 6, "Value types" section: my Dog $spot; my $spot returns $dog; my $spot of Dog; our Animal sub get_pet() {...} sub get_pet() returns Animal {...} sub get_pet() of Animal {...} The $dog in the second line is obviously a typo. Let's ignore it. The above paragraph implies that these two statements are equivalent: my Dog $spot; my $spot of Dog; So we know $spot has a value type of Dog. But what is its implementation type? We turn to the "Implementation types" section: my $spot is Scalar; # this is the default Hence, these two statements are equivalent: my Dog $spot; my $spot of Dog is Scalar; Now we turn to to "Hierarchical types": my Egg @carton; # each elem is an Egg Okay. So "Egg" is the value type for elements in @carton. But what is the implementation type of @carton? my @carton of Egg is Scalar; # is @carton Scalar? my @carton of Egg is Array; # is @carton Array? S06 does not cover this point, which leads to a very bad case of ambiguity. Below I will show that both interpretation are troublesome. Let's take the first one first, because it is what S06 seems to imply, although it is against Perl5's tie() intuition: my @carton is Scalar; # assuming this is the default Now @carton implements the same set of behaviour as $spot. It essentially means that every variable is a scalar variable, and the only different of @carton vs $spot is that @carton applies list context to its right hand side in assignment and binding, while $spot applies scalar context. It also means that: tie($spot, PersistentScalar); tie(@carton, PersistentScalar); are both valid and means essentially the same thing. Extending this metaphor, we see that: tie($spot, SDBM_File, :file<foo>); tie(@carton, SDBM_File, :file<foo>); tie(%dbm, SDBM_File, :file<foo>); Needs to have the same semantic. Here my intuition stops short; I cannot fathom how the three lines above "means" the same thing. Having shown the problem with the "@carton is Scalar" model, let's turn to the second possibility, based on our intuitions from Perl5's tying system: my @carton is Array; # assuming this is the default However, by this assumption, the next line in "Hierarchical types" has to be interpreted thus: my Array of Egg @box; # each elem is an array of Eggs my @box of Array of Egg is Array; # by the assumption above In the second line above, the first "Array" is a Value Type (following "of"), but the second one is an Implementation Type (following "is"). However, since a V-Type has to implement a different set of behaviour than an I-Type, they should persumably using different names. But let's assume S06 is correct, and such "punning" is allowed: I-Type and V-Type, being in separate namespaces, may use the same name. Now consider this function declaration: multi sub do_something (Dog $x) { ... } This &do_something function is only triggered with $x has a type of Dog. However, is it talking about the I-Type here, or the V-Type? From all indications, this seems to be talking about V-Type. For example, from the "The &?SUB routine" section, we have: my $anonfactorial = sub (Int $n) { ... }; Here "Int" clearly refers to $n's value; one cannot fathom that $n has to be tied to the Int implementation to enter this function! But then, how should we declare implement the PersistentScalar I-Type itself? By Synopsis 12 version 4, it should be declared as a Trait Class: class PersistentScalar { multi sub trait_auxiliary:is( Class $base, Any $container ) { $container does PersistentScalar() } } However, PersistentScalar really only want scalars, not arrays, as its container type. Where do we specify it? Is the sigil on "$container" enough to do that? S12 does not say more on this subject. But let us assuming that it is by using the sigil's (assumed) defaulting rule of "is Scalar": class PersistentScalar { multi sub trait_auxiliary:is( Class $base, Any $container is Scalar ) { $container does PersistentScalar() } } Furthermore, let's consider another I-Type Class, "DatabaseScalar", that can only take containers that already "is PersistentScalar": class DatabaseScalar { multi sub trait_auxiliary:is( class $base, Any $container is PersistentScalar ) { $container does DatabaseScalar() } } Then, how should $spot be defined? my $spot is DatabaseScalar is PersistentScalar; # like this? my $spot is PersistentScalar is DatabaseScalar; # or this? Or does both work equally well? Why? Also, considering that punning is allowed, does the form below work? Why? my $spot is DatabaseScalar of DatabaseScalar is PersistentScalar of PersistentScalar; Finally, consider this example from "Value types" of S06: my Rat %ship; # the value of each entry stores a Rat What if I'd like to declare the V-Type of keys to %ship? Is that a valid question? Is it always "Any"? Why? Again, my sincere apologies for not making my question clear the first time. Thanks, /Autrijus/
pgpPn682DHnBz.pgp
Description: PGP signature