<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/

Attachment: pgpPn682DHnBz.pgp
Description: PGP signature

Reply via email to