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

Re: Instance attributes collision

1 view
Skip to first unread message

Chromatic

unread,
Feb 12, 2006, 9:20:55 PM2/12/06
to perl6-l...@perl.org, Yiyi Hu
On Sunday 12 February 2006 17:11, Yiyi Hu wrote:

> For perl 6,
> Array and Scalar are in different namespace.
> So,
> class A { has $.a; has @.a };
>
> what will A.new.a return by default?
>
> An Error? or Scalar has a higher priority?

Seems like a compile-time warning (at least) to me.

-- c

Luke Palmer

unread,
Feb 13, 2006, 4:36:45 AM2/13/06
to Yiyi Hu, perl6-l...@perl.org
On 2/13/06, Yiyi Hu <yiy...@gmail.com> wrote:
> For perl 6,
> Array and Scalar are in different namespace.
> So,
> class A { has $.a; has @.a };
>
> what will A.new.a return by default?

That's a compile time error. Both "has" declarations generate a
method "a", so it is a method conflict.

Luke

Juerd

unread,
Feb 13, 2006, 4:40:55 AM2/13/06
to perl6-l...@perl.org
Luke Palmer skribis 2006-02-13 9:36 (+0000):

> That's a compile time error. Both "has" declarations generate a
> method "a", so it is a method conflict.

Doesn't normally double declaration end in the later masking/overriding
the earlier declaration, with a warning, but not an error?

I'd expect

has $.a;
has @.a;

To result in both $.a and @.a, but only one method .a, which is an
accessor for @.a


Juerd
--
http://convolution.nl/maak_juerd_blij.html
http://convolution.nl/make_juerd_happy.html
http://convolution.nl/gajigu_juerd_n.html

Luke Palmer

unread,
Feb 13, 2006, 4:46:12 AM2/13/06
to Juerd, perl6-l...@perl.org
On 2/13/06, Juerd <ju...@convolution.nl> wrote:
> Luke Palmer skribis 2006-02-13 9:36 (+0000):
> > That's a compile time error. Both "has" declarations generate a
> > method "a", so it is a method conflict.
>
> Doesn't normally double declaration end in the later masking/overriding
> the earlier declaration, with a warning, but not an error?

Does it?

role Foo {
method bar() { "x" }
}
role Bar {
method bar() { "y" }
}

class Baz {
does Foo;
does Bar; # does this count as double declaration?
}

I'd say we're going more toward the conflict side of things. That is,
I'd expect:

sub foo() { 1 }
sub foo() { 2 }

To be an error. However, I'd expect:

sub foo() { 1 }
&foo ::= sub () { 2 };

Not to be.

Luke

Juerd

unread,
Feb 13, 2006, 5:33:00 AM2/13/06
to perl6-l...@perl.org
Luke Palmer skribis 2006-02-13 9:46 (+0000):

> class Baz {
> does Foo;
> does Bar; # does this count as double declaration?
> }

I'd put composition and inheritance in a slightly different category
than accessor *generators*.

Stevan Little

unread,
Feb 14, 2006, 10:51:46 PM2/14/06
to Yiyi Hu, perl6-l...@perl.org
On 2/12/06, Yiyi Hu <yiy...@gmail.com> wrote:
> For perl 6,
> Array and Scalar are in different namespace.
> So,
> class A { has $.a; has @.a };
>
> what will A.new.a return by default?
>
> An Error? or Scalar has a higher priority?

It seems to me that the best way to approach this issue is to seperate
the accessor generation from the attribute declaration.

To start with, in Perl 5, it is entirely possible to do this without ambiguity:

package Foo;
our $bar;
our @bar;

This is because '$bar' and '@bar' are different names. Perl 6 should
follow this, and store the meta-objects which represent these
attributes using different names as well, so given:

class A {
has $.a;
has @.a
};

You would find two attribute meta-objects, one keyed to '$.a' and the
other to '@.a', and there is no ambiguity.

Now for the accessor generation portion of this question.

Accessor generation should probably take place towards the end of
class construction. You need to think of class construction as a
multi-step process, first the name is encountered:

class A;

At this point a metaclass should be created and named A. Next the body
of the class should be evaluated within the context of the metaclass.
As each attribute declaration is encountered, it should be converted
to metaclass calls to further construct the class. So things like
this:

has $.a;

Will translate to something like this:

$::CLASS.add_attribute(Perl6::Meta::Attribute.new(:name<$.a>));

Now, when the classes body has been completely evaluated, a method
should be called on the metaclass (found in the $::CLASS
pseudo-lexical variable) to tell the metaclass that that class
construction has been finished. This method should finish up the class
construction and at this point the attribute accessors should now be
generated.

Now, here is my proposal for how accessor generation should be handled.

I think that the metaclass (stored in the pseudo-lexical $::CLASS)
should create a number of anonymous roles on the fly:

role {
multi method a (::CLASS $self) { ... }
multi method a (::CLASS $self, Scalar $value) { ... }
}

role {
multi method a (::CLASS $self) { ... }
multi method a (::CLASS $self, Array @value) { ... }
}

These roles would then be added to the metaclass using the normal
rules of role composition. (NOTE: I assume that ::CLASS is unbound
until the role is composed into a class, I think A12 might have stated
this detail)

Now obviously we have a conflict in our multi-methods. S12 only states
that multi methods will be compared by their long names (name +
signature) to resolve ambiguity, it does not state what happens when
those long names conflict. I propose that they work just as normal
method conflicts do, which is that both methods are excluded and the
consuming class is then required to implement that method.

So now, if we follow the rules of role composition, when these two
anonymous roles are added to the metaclass, there will be a conflict
and class composition will fail.

So the short answer is that this:

class A {
has $.a;
has @.a
};

will result in a fatal compile time error, while this:

class A {
has $.a;
has @.a

multi a ($::CLASS) {
# do something here,.. I dont know what :)
}
};

will not fail.

Hope this helps :)

Stevan

Rob Kinyon

unread,
Feb 15, 2006, 7:44:53 AM2/15/06
to Stevan Little, Yiyi Hu, perl6-l...@perl.org
On 2/14/06, Stevan Little <stevan...@gmail.com> wrote:
> I think that the metaclass (stored in the pseudo-lexical $::CLASS)
> should create a number of anonymous roles on the fly:
>
> role {
> multi method a (::CLASS $self) { ... }
> multi method a (::CLASS $self, Scalar $value) { ... }
> }
>
> role {
> multi method a (::CLASS $self) { ... }
> multi method a (::CLASS $self, Array @value) { ... }
> }
>
> These roles would then be added to the metaclass using the normal
> rules of role composition. (NOTE: I assume that ::CLASS is unbound
> until the role is composed into a class, I think A12 might have stated
> this detail)
>
> Now obviously we have a conflict in our multi-methods. S12 only states
> that multi methods will be compared by their long names (name +
> signature) to resolve ambiguity, it does not state what happens when
> those long names conflict. I propose that they work just as normal
> method conflicts do, which is that both methods are excluded and the
> consuming class is then required to implement that method.

Is it just the first multimethod a(::CLASS $self) from each role being
excluded or are all the multimethod a(...)'s being excluded?

Rob

Stevan Little

unread,
Feb 15, 2006, 9:09:20 AM2/15/06
to Rob Kinyon, Yiyi Hu, perl6-l...@perl.org

I would think it could be the first one only, the one where the long
name conflicts.

Stevan

0 new messages