<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
