Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

is rw trait's effect on signature

5 views
Skip to first unread message

Aaron Sherman

unread,
May 6, 2004, 1:39:36 PM5/6/04
to Perl6 Language List
There's a subtle problem / feature resulting from the "is rw" trait that
may be so obvious that I'm making a fool of myself, or it might be that
it's not yet occurred, but I don't recall seeing discussion of it.

The simple case is:

sub foo(X $i is rw) {...}
class X {...}
class Y {...}
my Y $var = 'something';
foo($var);

In this case, something kind of interesting has to happen.

Either the signature checking has to verify that Y isa X (and thus can
be used polymorphically as X, not just converted to X) ...

... or, it has to do something of the sort:

{ my X $tmp = $var; foo($tmp); $var = $tmp; }

which has its own problems, of course.

Were either of these the intention or am I missing something?

"is ref" probably has the same concern.
--
Aaron Sherman <a...@ajs.com>
Senior Systems Engineer and Toolsmith
"It's the sound of a satellite saying, 'get me down!'" -Shriekback


Dan Sugalski

unread,
May 6, 2004, 1:43:59 PM5/6/04
to Perl6 Language List
At 1:39 PM -0400 5/6/04, Aaron Sherman wrote:
>There's a subtle problem / feature resulting from the "is rw" trait that
>may be so obvious that I'm making a fool of myself, or it might be that
>it's not yet occurred, but I don't recall seeing discussion of it.
>
>The simple case is:
>
> sub foo(X $i is rw) {...}
> class X {...}
> class Y {...}
> my Y $var = 'something';
> foo($var);
>
>In this case, something kind of interesting has to happen.
>
>Either the signature checking has to verify that Y isa X (and thus can
>be used polymorphically as X, not just converted to X) ...
>
>... or, it has to [convert]

... or it pitches a runtime type error.
--
Dan

--------------------------------------"it's like this"-------------------
Dan Sugalski even samurai
d...@sidhe.org have teddy bears and even
teddy bears get drunk

Chromatic

unread,
May 6, 2004, 1:44:10 PM5/6/04
to Aaron Sherman, Perl6 Language List
On Thu, 2004-05-06 at 10:39, Aaron Sherman wrote:

> The simple case is:
>
> sub foo(X $i is rw) {...}
> class X {...}
> class Y {...}
> my Y $var = 'something';
> foo($var);
>
> In this case, something kind of interesting has to happen.
>
> Either the signature checking has to verify that Y isa X (and thus can
> be used polymorphically as X, not just converted to X) ...

I'd argue 'Y does X', actually, though Dan disagrees and says "Well,
whatever!"

-- c

Dan Sugalski

unread,
May 6, 2004, 1:52:45 PM5/6/04
to chromatic, Aaron Sherman, Perl6 Language List

Nope. Dan says "Is that X in the signature an assertion of interface
or of parentage?" and has the Perl 6 compiler emit the appropriate
code. (Parentage is the safer option generally, since only in perl 6
is the class == interface assertion going to be true, and you might
want to be able to yank in Python/Ruby/Perl5/Objective-C/Java/C#/C++
objects and classes. Or... you might not, which is fine too)

Larry Wall

unread,
May 6, 2004, 2:03:44 PM5/6/04
to Perl6 Language List
On Thu, May 06, 2004 at 01:52:45PM -0400, Dan Sugalski wrote:
: At 10:44 AM -0700 5/6/04, chromatic wrote:
: >On Thu, 2004-05-06 at 10:39, Aaron Sherman wrote:
: >
: >> The simple case is:
: >>
: >> sub foo(X $i is rw) {...}
: >> class X {...}
: >> class Y {...}
: >> my Y $var = 'something';
: >> foo($var);
: >>
: >> In this case, something kind of interesting has to happen.
: >>
: >> Either the signature checking has to verify that Y isa X (and thus can
: >> be used polymorphically as X, not just converted to X) ...
: >
: >I'd argue 'Y does X', actually, though Dan disagrees and says "Well,
: >whatever!"
:
: Nope. Dan says "Is that X in the signature an assertion of interface
: or of parentage?" and has the Perl 6 compiler emit the appropriate
: code. (Parentage is the safer option generally, since only in perl 6
: is the class == interface assertion going to be true, and you might
: want to be able to yank in Python/Ruby/Perl5/Objective-C/Java/C#/C++
: objects and classes. Or... you might not, which is fine too)

I don't see a problem with using "does" sematics in Perl 6 because
roles and classes live in the same namespace, and "does" naturally
devolves to "isa" semantics if you hand it a class. So we just
"render unto classes the things that are class's, and unto roles the
things that are role's", as it were. So the X in the signature is
always an assertion of interface, which may or may not care about
parentage--and which may care about *extra* things if X is a subtype
that adds constraints. But subtypes also live in the same namespace
as classes and roles, so again, we know almost immediately what kind
of checking is required.

Larry

Dan Sugalski

unread,
May 6, 2004, 2:24:18 PM5/6/04
to Perl6 Language List
At 11:03 AM -0700 5/6/04, Larry Wall wrote:
>On Thu, May 06, 2004 at 01:52:45PM -0400, Dan Sugalski wrote:
>: At 10:44 AM -0700 5/6/04, chromatic wrote:
>: >On Thu, 2004-05-06 at 10:39, Aaron Sherman wrote:
>: >
>: >> The simple case is:
>: >>
>: >> sub foo(X $i is rw) {...}
>: >> class X {...}
>: >> class Y {...}
>: >> my Y $var = 'something';
>: >> foo($var);
>: >>
>: >> In this case, something kind of interesting has to happen.
>: >>
>: >> Either the signature checking has to verify that Y isa X (and thus can
>: >> be used polymorphically as X, not just converted to X) ...
>: >
>: >I'd argue 'Y does X', actually, though Dan disagrees and says "Well,
>: >whatever!"
>:
>: Nope. Dan says "Is that X in the signature an assertion of interface
>: or of parentage?" and has the Perl 6 compiler emit the appropriate
>: code. (Parentage is the safer option generally, since only in perl 6
>: is the class == interface assertion going to be true, and you might
>: want to be able to yank in Python/Ruby/Perl5/Objective-C/Java/C#/C++
>: objects and classes. Or... you might not, which is fine too)
>
>I don't see a problem with using "does" sematics in Perl 6 because
>roles and classes live in the same namespace, and "does" naturally
>devolves to "isa" semantics if you hand it a class.

Well... sort of, but only because you've defined that for perl 6
classes automatically do themselves--you've conflated inheritance and
interface. Which is fine, except that it falls down in the face of
objects from classes that don't do that.

We can't devolve to isa checking under the hood, because there are
cases where a class can assert that it has a role without pulling in
the role externally. (Storable, for example, will be a likely thing
here as classes assert they do Storable without pulling in an
external Storable role, since a generic Storable's generically
useless) So there will be classes that have a role in them without
having a class of the same name in their inheritance hierarchy
anywhere.

Does, though, can only check the assertions of whether a class does
the role in question--it can't check inheritance, because while Perl
6 makes roles and classes more or less the same (kinda sorta) that's
not true of other languages. If I have an Objective-C or Java object
of class Foo, and Foo implements the Bar interface, then that object
does(Bar) while not being isa(Bar), and isa(Foo) without does(Foo).
Ruby's mixins behave similarly.

In an all-Perl 6 environment it should work out OK if Perl 6's
signature checking conflates isa and does (unless you're going to add
a "doesn't" to class definitions :) but it's going to make things
potentially interesting in a mixed-language environment which is
reasonably likely.

Not, mind you, that it necessarily matters, but it's good to make
sure things are clear (whether it's an isa or a does check) and it
may be useful to have specific syntax if people want to be explicit
whether they're checking isa or does. (Or can, I suppose, if you want
to go that far)

Chromatic

unread,
May 6, 2004, 2:42:49 PM5/6/04
to Dan Sugalski, Perl6 Language List
On Thu, 2004-05-06 at 11:24, Dan Sugalski wrote:

> Well... sort of, but only because you've defined that for perl 6
> classes automatically do themselves--you've conflated inheritance and
> interface. Which is fine, except that it falls down in the face of
> objects from classes that don't do that.

Given:

- class A, a superclass
- class AB, a subclass of A
- class Eh, a class that does A but does not inherit from it
- subroutine signature foo(A some_object)

If the signature checker checks isa, you can't pass in Eh, even though
its writer has guaranteed that its semantics match those of A.

If the signature checker checks does, you can pass in A, AB, or Eh,
assuming that subclassing marks does on the subclass *or* that you fall
back to checking isa if does fails.

Either will probably work, but you and I both agree there's a problem in
that does and isa overlap somewhat. We disagree on the implications of
that overlap, though.

Both can answer the question "can this object handle this method?" isa
goes further, though, telling you where to look for the method if it's
not part of the class itself.

That's why I'm not sure making isa the base operation is the right
behavior. If you put does alongside it, you have two mechanisms by
which people can answer the same question -- not only is that kind of a
waste, but people will do that incorrectly. If you put does atop isa,
you're getting less specific and throwing out information.

If you make does the base operation, you can be more specific with isa
(or delegates or aggregates, if you want to be that specific) by
separating the method lookup part.

As a plus, languages that don't care about does don't have to do expose
it. I can't see a place where it falls down -- but if some Perl 6 code
asks a does question about a Ruby object, it just works.

-- c

Dan Sugalski

unread,
May 6, 2004, 3:09:47 PM5/6/04
to chromatic, Perl6 Language List
At 11:42 AM -0700 5/6/04, chromatic wrote:
>On Thu, 2004-05-06 at 11:24, Dan Sugalski wrote:
>
>> Well... sort of, but only because you've defined that for perl 6
>> classes automatically do themselves--you've conflated inheritance and
>> interface. Which is fine, except that it falls down in the face of
>> objects from classes that don't do that.
>
>Given:
>
> - class A, a superclass
> - class AB, a subclass of A
> - class Eh, a class that does A but does not inherit from it
> - subroutine signature foo(A some_object)
>
>If the signature checker checks isa, you can't pass in Eh, even though
>its writer has guaranteed that its semantics match those of A.
>
>If the signature checker checks does, you can pass in A, AB, or Eh,
>assuming that subclassing marks does on the subclass *or* that you fall
>back to checking isa if does fails.
>
>Either will probably work, but you and I both agree there's a problem in
>that does and isa overlap somewhat. We disagree on the implications of
>that overlap, though.

It's a matter of perspective as much as anything else. And, I'll add
again, I don't care which it is. Both ways have implications and
limits, and either way is fine.

Austin Hastings

unread,
May 6, 2004, 4:27:14 PM5/6/04
to Perl6 Language List

> -----Original Message-----
> From: chromatic [mailto:chro...@wgz.org]
>
> Given:
>
> - class A, a superclass
> - class AB, a subclass of A
> - class Eh, a class that does A but does not inherit
> from it
> - subroutine signature foo(A some_object)
>
> If the signature checker checks isa, you can't pass in Eh,
> even though its writer has guaranteed that its semantics
> match those of A.
>
> If the signature checker checks does, you can pass in A,
> AB, or Eh, assuming that subclassing marks does on the
> subclass *or* that you fall back to checking isa if does
> fails.
>

I think we had this discussion a year or two ago, and Damian was opposed to
the notion that providing the correct methods was equivalent to providing
the interface or belonging to the class.

His reasoning involved Dog and Tree both sharing grow, bark, etc.

Perhaps he could re-explain his reasoning?

=Austin

Chromatic

unread,
May 6, 2004, 4:35:38 PM5/6/04
to Austin Hastings, Perl6 Language List
On Thu, 2004-05-06 at 13:27, Austin Hastings wrote:

> I think we had this discussion a year or two ago, and Damian was opposed to
> the notion that providing the correct methods was equivalent to providing
> the interface or belonging to the class.
>
> His reasoning involved Dog and Tree both sharing grow, bark, etc.
>
> Perhaps he could re-explain his reasoning?

I agree with his reasoning. You need some sort of context to determine
whether bark() is a noun or a verb -- that'd be the name of the class
(or the role, in my scheme).

Trying to infer which role might apply may be nice in some cases, but as
a general matter of policy it seems pretty vague and corner-casey. I'm
comfortable saying "if you don't mark 'does' and you don't inherit, the
compiler won't guess that you do."

-- c

Austin Hastings

unread,
May 6, 2004, 4:47:37 PM5/6/04
to Perl6 Language List

> -----Original Message-----
> From: chromatic [mailto:chro...@wgz.org]

> Sent: Thursday, 06 May, 2004 04:36 PM
> To: Austin Hastings
> Cc: Perl6 Language List
> Subject: RE: is rw trait's effect on signature
>
>
> On Thu, 2004-05-06 at 13:27, Austin Hastings wrote:
>
> > I think we had this discussion a year or two ago, and Damian
> > was opposed to the notion that providing the correct methods
> > was equivalent to providing the interface or belonging to
> > the class.
> >
> > His reasoning involved Dog and Tree both sharing grow, bark,
> > etc.
> >
> > Perhaps he could re-explain his reasoning?
>
> I agree with his reasoning. You need some sort of context to
> determine whether bark() is a noun or a verb -- that'd be the
> name of the class (or the role, in my scheme).

IMO, "Mom's rule" applies in this case.

>
> Trying to infer which role might apply may be nice in some
> cases, but as a general matter of policy it seems pretty
> vague and corner-casey. I'm comfortable saying "if you
> don't mark 'does' and you don't inherit, the compiler
> won't guess that you do."

Then in your example:

> Given:
> - class A, a superclass
> - class AB, a subclass of A
> - class Eh, a class that does A but does not inherit
> from it
> - subroutine signature foo(A some_object)

The class 'Eh' "does A but does not inherit", did you mean:

class Eh {
method A1
method A2
method A3
}

or did you mean

class A {...}
class Eh {
does A;
}

instead? I had thought that C<does CLASS> (class implicitly= role) had been
rejected.

=Austin


Chromatic

unread,
May 6, 2004, 6:36:38 PM5/6/04
to Austin Hastings, Perl6 Language List
On Thu, 2004-05-06 at 13:47, Austin Hastings wrote:

> Then in your example:


> The class 'Eh' "does A but does not inherit", did you mean:
>
> class Eh {
> method A1
> method A2
> method A3
> }

Yes.

> I had thought that C<does CLASS> (class implicitly= role) had been
> rejected.

I don't remember in particular, but it's not hard to rejig the example
to achieve the same sort of effect. The important point is that I think
using 'isa' to mean 'does' is silly.

-- c

Mark Sparshatt

unread,
May 6, 2004, 2:39:43 PM5/6/04
to perl6-l...@perl.org
Dan Sugalski wrote:

>
> We can't devolve to isa checking under the hood, because there are
> cases where a class can assert that it has a role without pulling in
> the role externally. (Storable, for example, will be a likely thing
> here as classes assert they do Storable without pulling in an external
> Storable role, since a generic Storable's generically useless) So
> there will be classes that have a role in them without having a class
> of the same name in their inheritance hierarchy anywhere.
>
> Does, though, can only check the assertions of whether a class does
> the role in question--it can't check inheritance, because while Perl 6
> makes roles and classes more or less the same (kinda sorta) that's not
> true of other languages. If I have an Objective-C or Java object of
> class Foo, and Foo implements the Bar interface, then that object
> does(Bar) while not being isa(Bar), and isa(Foo) without does(Foo).

I'm not sure that this is correct. In Java if you write the following code

class Foo implements Bar
{
}

then Foo.new instanceof Bar == true

> Ruby's mixins behave similarly.
>

Actually Ruby uses inheritance to implement mixins. running the
following code

module TestMod
end

class TestClass
include TestMod
end

creates an anomynous class that contains a reference to TestMod. This is
used as the superclass of TestClass

p TestClass.ancestors #=> [TestClass, TestMod, Object, Kernel]

--
Mark Sparshatt


0 new messages