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

Reply via email to