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/
Thanks to Jonathan Scott Duff's off-list hint, A06 did show that
the second model is more correct. That's what I get from basically
ignoring the Apocalypses during implementation. :-/ I stand corrected.
Won't do that again.
Attached is the patch to S06.pod that adds the two bits of information
I'd like to see. The $dog typo has been fixed a week ago.
However, I'd still like to know whether my understanding on punning
(same class 'Array' used as both Implementation Type and Value Type)
and the validity of matching on "$var is TraitName" in subroutine
signatures is correct. That, and types of hash keys. :)
Thanks,
/Autrijus/
--- S06.pod.orig Fri Feb 4 04:29:34 2005
+++ S06.pod Fri Feb 4 04:29:07 2005
@@ -650,6 +650,7 @@
Class Perl 6 standard class namespace
Object Perl 6 object
Grammar Perl 6 pattern matching namespace
+ Pair Perl pair
List Perl list
Lazy Lazily evaluated Perl list
Eager Non-lazily evaluated Perl list
@@ -685,6 +686,7 @@
The implementation type specifies how the variable itself is implemented. It is
given as a trait of the variable:
+ my @carton is Array; # this is the default
my $spot is Scalar; # this is the default
my $spot is PersistentScalar;
my $spot is DataBase;
Either that, or the Ref value type is designed to wrap an
implementation type. I'm not sure which is the case.
--
Brent 'Dax' Royal-Gordon <br...@brentdax.com>
Perl and Parrot hacker
"For those of you that can't spell, this site also contains free
imags, iamges, imges, picturs, pcitures, picktures, picturess, and
pistures."
Hmm, it's actually more subtle than that, because Perl6's Array
does not require that each element have the same value type, so a
closer approximation is via existential types -- i.e. for each
element in an array of value type 't3', there must exist an instance
of "TScalar t3", but each element's value-type may differ from
each other; I think that's what the "Any" above means.
However, I wonder how to talk about an array that can contain elements
of any value type, but all the elements must have the same type.
Is Perl6 capable of expressing such a restraint?
Thanks,
/Autrijus/
Can you elaborate? Do you mean the two below are equivalent?
# Something that agrees with the Perl5 model
my @array of Array;
my @array is Array of (Ref of (Any is Array) is Scalar)
> I'm not sure which is the case.
Another possible interpretation is that "of TraitName" automatically
exapnds to "of (Any is TraitName)", which will alleviate the need of a
separate "Ref" above:
# Something that does not quite agree with the Perl5 model
my @array of Array;
my @array is Array of (Any is Array of (Any is Scalar))
If so, may I consider it as equivalent to this Haskell code?
class TArray baseVtype elemVtype where {- ... -} -- Array Trait
class TScalar baseVtype where {- ... -} -- Scalar Trait
myArray :: (TArray t1 t2, TArray t2 t3, TScalar t3) => t1
That is, "myArray" matches any value type (t1) that is an instance of
the TArray type-class interface, with its elemVtype (t2) is also an
interface of TArray, and t2's elemVtype (t3) must be an instance of
the TScalar type-class. Which means this equivalency should hold:
Perl6 Trait <===> Haskell TypeClass
Perl6 ValueType <===> Haskell Type
Please let me know whether this interpretation is valid. :)
Thanks,
/Autrijus/
Yes, I have read the OOHaskell paper and traced the hideously clever
HList code. However, as I'm not doing Perl6->Haskell translator,
but merely a Perl6 interpreter, so OOHaskell's model, whilst
interesting, is of only academic interest to me. :)
What I'd like to know is (again) the operational semantic of "Array of
Array"; is the two "Array" puns that happens to share a class name, or
is it a shorthand for existential types, or is it a shorthand for the
"Ref" type that looks and acts like the Data.Dynamic type in haskell?
Or something else altogether?
Thanks,
/Autrijus/
>However, I wonder how to talk about an array that can contain elements
>of any value type, but all the elements must have the same type.
>Is Perl6 capable of expressing such a restraint?
>
>Thanks,
>/Autrijus/
>
>
The problem (in general) with this requirement is that it conflicts with
inhericance. Perl6 allows you to extend any type (using 'but' operator,
for example) and so, any time you promise that something will be of a
certain type, the type's children will be allowed. That's at least the
way I read A12. I also think that juntions will have their elements'
type's interface and so they can also pose for any type. In other words,
you need a real polymorphic object system in Haskell for this to work.
Fortunately there's one handily described at
http://homepages.cwi.nl/~ralf/OOHaskell/
While we're on the topic, which of the following are true?
3 but "three" ~ int (false?)
3 but "three" ~ Integer (true?)
3 & 5 ~ int (true?)
3 & 5 ~ Integer (true?)
(Skipping off topic, to Parrot. Sorry. :) ) If 3 & 5 is actually int,
and this is only determinable at runtime, to me this seems like a
problem with I# register allocation - ints can't be reliably assigned to
I# registers. Unless, of course, you autothread at the point when a
junction has to be cast into an int. Do I understand junction semantics
correctly?
Miro
I asked that before, and answer was:
> On Tue, 30 Nov 2004 14:13:52 -0800, Larry Wall wrote:
> ...
> I think the only place they differ is in list context. @a always
> interpolates, and $a never does.
and everywhere else they would work the same.
rather little difference to have different "namespaces", huh?
I still have some doubts. How could I make a reference to array?
looks like this should work in perl6, because of scalar context:
$arref = @arr;
or the perl5 way. is it the same somehow? or is it wrong in perl6?
$arref = \@arr;
and the mentioned problem is interesting too..
my @array is Scalar; # this isn't the default, as I know
@array = (1,2,3);
how such a weird var would behave?
my $var = "test";
my @arr := $var;
error? or maybe it would be the same weirdness, like in former example? or
maybe it's a ["test"]?
The := operator uses the same rules as parameter passing. So, what do
you think this does?
sub foo(@arr) {...}
foo($var);
I would assume the answer is "syntax error". (Remember, array
parameters don't slurp in Perl 6 unless they have a *.)
Not really "syntax error", but runtime error. The function is expecting
an array, and it gets a string.
This is perfectly legal:
sub foo(@arr) {...}
my $var = [1,2,3];
foo($var);
And it works just as if there were an @ on the front of var.
Luke