my Hash of Array of Recipe %book;
my Hash[returns=>Array[returns=>Recipe]] %book;
And later:
class LoudArray is Array { ... }
Clearly, here Hash and Array are used as instantiable, generic classes,
instead of mere roles. Does this need to change, or can we lift the
ban on type-parameterized classes?
Thanks,
/Autrijus/
I think the distinction is still useful to document that there are
still unbound types. What we need to emphasize is that a role can be
used as a class, at which point any unbound types are bound to Any,
or whatever we're calling it these days. I'd say Array is a role,
not a class. So these all might do different things:
class LoudArray is Array { ... }
role LoudArray does Array { ... }
role LoudArray is Array { ... }
Interestingly, what is bound by trait as a container type can still be
a role rather than a class, since the actual class might not be instantiated
till we know the shape, and that might not be known till the time of
elaboration of the variable declaration:
my num @array is shape($x,$y);
That's assuming we treat shapes as a type signature... It doesn't have to
be for integer indexes, maybe, but for hashes:
my Fight %hash is shape(Dog,Cat);
it looks susupiciously like a type signature. Maybe it should be written:
my Fight %hash :(Dog,Cat);
or even
my %hash :(Dog,Cat --> Fight);
Larry
It means that when MyPoint is finally nailed down into a class, that
class will inherit from Point. The role itself doesn't inherit.
Larry
So the last line means a role can be used just like a class, and
_inherit_ its behaviour as well?
role Point { has $.x; has $.y; method move_right { $.x++ } };
role MyPoint is Point {
method move_right { ./SUPER::move_right(); $.y++; }
}
Thanks,
/Autrijus/
Aye. But if a Role can be inherited _from_, then this should
work too, right?
role Point {
has $.x; has $.y;
method move_right { $.x++ }
};
role OurPoint is Point {
method move_right { ./SUPER::move_right; $.y++ }
}
role MyPoint is MyPoint {
method move_right { ./SUPER::move_right; $.x++ }
}
my MyPoint $point .= new( :x(0) :y(0) );
$point.move_right;
say $point.x; # 2
say $point.y; # 1
Thanks,
/Autrijus/
s:2nd/MyPoint/OurPoint/ I presume.
: method move_right { ./SUPER::move_right; $.x++ }
: }
:
: my MyPoint $point .= new( :x(0) :y(0) );
: $point.move_right;
: say $point.x; # 2
: say $point.y; # 1
Sure, except that you're not really inheriting from a role here.
You're really inheriting from an anonymous class of the same name. :-)
Much like: "The Illiad was not written by Homer, but by another blind
8th-century poet of the same name."
Basically, I'd like to keep the distinction that a class is a
valid dispatcher while a role is not. This is mostly a declarative
distinction to keep it straight in people's heads. But as with many
other things in Perl, if you use an X as a Y, it'll behave like one,
and so we try to make it easy for a role to "autovivify" itself in
a class context.
Larry
Hmm, "Anonymous class with the name 'Array of Any'" sounds like
an oxymoron. Also consider:
role Foo {};
my Foo $x .= new;
my Foo $y .= new;
ref($x) eqv ref($y); # bool::true, surely?
If all the anonymous classes are actually the same class underneath, and
have the name that's identical to the role name, then where do their
"anonymousness" manifest?
Can we simply say "Foo" is a role can double as a class -- i.e. you
can choose to "is" it or "does" it? Then it follows that "Array of Any"
is a class, and "Array of Int" is also a class, etc.
Thanks,
/Autrijus/