develooper Front page | perl.perl6.language | Postings from February 2005

Retry: ITypes and VTypes.

Thread Next
Autrijus Tang
February 3, 2005 12:08
Retry: ITypes and VTypes.
Message ID:
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.

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.

Thread Next Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at | Group listing | About