On Fri, Dec 12, 2003 at 09:36:45AM +0000, Andy Wardley wrote: : Larry Wall wrote: : > Anyway, this all implies that use of a role as a method name defaults to : > returning whether the type in question matches the subtype. That is, : > when you say: : > : > $foo.true : > $bar.red : [...] : > $bar.red : [...] : > $baz.Byte : > : > it's asking whether the Int property fulfills the Byte constraint, but : > that's getting kind of strange. : : If the roles are first class objects then their traits are defined : as methods, right? : : Boolean.true($foo) : Color.red($bar) : Int.byte($baz)
Potentially, though roles are more properly thought of as types than classes. That is, they're abstract sets of values. You can instantiate one sufficiently well to take a reference to it, so that you can do $someobject but= $somerole; But it's not really an object in its own right, and it's not clear that you can call any of the methods it defines unless it's part of an object. : Then assuming that certain objects "inherit" certain roles, you could : use something like the Perl 5 $self->SUPER::new() syntax. Only it would : look more like this: : : $foo->Boolean.true : $bar->Color.red : $baz->Int.byte Well, we can't use -> because we're using that for something else. But it's certainly true that we'll have to have some mechanism for disambiguating Color.green from Blackberry.green. After all, Blackberry.green == Color.red Or maybe it's Blackberry::green == Color::red I'm not sure how subtypes are related to types yet, syntactically speaking. Might even be Blackberry[green] == Color[red] : > Another implication is that, if properties are subtypes, we can't use : > the same name as a cast method. Since : > : > $baz.Byte : > : > only returns true or false, we'd need something like (yuck) : > : > $baz.asByte : [...or...] : > $baz.as(Byte) : : Or: : $baz->Byte : : That would make something like this: : : $foo->Color.red : : the same kind of thing as: : : $foo.as(Color).red I'm thinking the ordinary method $foo.Color implies $foo.as(Color) meaning that we're viewing $foo through the Color filter. If you want to match against a value, however, you'd have to say $foo.Color == green or $foo.Color ~~ green In the latter case, you can just say $foo ~~ green as long as "green" is unambiguous. I don't know the syntax for disambiguating on the green end yet. Maybe one of $foo ~~ Color::green $foo ~~ Color.green $foo ~~ Color[green] Or maybe something else. The interesting question to me is what $ref = \$foo.as(Color); returns. It looks like a typed reference to me, but it's still a reference to the object in $foo, or can behave as one somehow. I don't think it should generate a reference to the bare role, because roles aren't intended to be first class objects (though you can force them to be, I think). Roles are supposed to encapsulate abstractions without implying objecthood. I think roles are a little bit like quarks--they're fine in theory, but it's scary to have loose ones floating around. So it seems to me that $foo.Color has to return some kind of typed ref to $foo, so that things like $foo.Color = purple; can work as expected. Staring at that, it seems apparent that .Color is simply an lvalue subroutine just like any other rw attribute. An lvalue sub can be thought of as a typed reference, I suppose. It gets more interesting if the role has multiple attributes though. What would \$foo.RGB return, I wonder, such that $foo.RGB = ($r,$g,$b) would work? Larry