Generic classes.

4 views
Skip to first unread message

Autrijus Tang

unread,
Aug 14, 2005, 8:28:33 AM8/14/05
to perl6-l...@perl.org
S06 made many explicit uses of generics as classes, which I find
difficult to reconcile with the "only roles takes type parameter"
ruling. For example:

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/

Larry Wall

unread,
Aug 15, 2005, 11:19:38 AM8/15/05
to perl6-l...@perl.org
On Sun, Aug 14, 2005 at 08:28:33PM +0800, Autrijus Tang wrote:
: S06 made many explicit uses of generics as classes, which I find

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

Larry Wall

unread,
Aug 15, 2005, 1:43:45 PM8/15/05
to perl6-l...@perl.org
On Tue, Aug 16, 2005 at 01:33:56AM +0800, Autrijus Tang wrote:
: On Mon, Aug 15, 2005 at 08:19:38AM -0700, Larry Wall wrote:
: > 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 { ... }
:
: 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++; }
: }

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

Autrijus Tang

unread,
Aug 15, 2005, 1:33:56 PM8/15/05
to perl6-l...@perl.org
On Mon, Aug 15, 2005 at 08:19:38AM -0700, Larry Wall wrote:
> 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 { ... }

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/

Autrijus Tang

unread,
Aug 15, 2005, 1:49:02 PM8/15/05
to perl6-l...@perl.org
On Mon, Aug 15, 2005 at 10:43:45AM -0700, Larry Wall wrote:
> : 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++; }
> : }
>
> It means that when MyPoint is finally nailed down into a class, that
> class will inherit from Point. The role itself doesn't inherit.

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/

Larry Wall

unread,
Aug 15, 2005, 2:07:51 PM8/15/05
to perl6-l...@perl.org
On Tue, Aug 16, 2005 at 01:49:02AM +0800, Autrijus Tang wrote:
: 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 {

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

Autrijus Tang

unread,
Aug 16, 2005, 2:49:29 PM8/16/05
to perl6-l...@perl.org
On Mon, Aug 15, 2005 at 11:07:51AM -0700, Larry Wall wrote:
> Sure, except that you're not really inheriting from a role here.
> You're really inheriting from an anonymous class of the same name. :-)

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/

Reply all
Reply to author
Forward
0 new messages