Re: Instance attributes collision

2006-02-15 Thread Rob Kinyon
On 2/14/06, Stevan Little [EMAIL PROTECTED] 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


Re: Instance attributes collision

2006-02-15 Thread Stevan Little
On 2/15/06, Rob Kinyon [EMAIL PROTECTED] wrote:
 On 2/14/06, Stevan Little [EMAIL PROTECTED] 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?

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

Stevan


Re: Instance attributes collision

2006-02-14 Thread Stevan Little
On 2/12/06, Yiyi Hu [EMAIL PROTECTED] 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


Re: Instance attributes collision

2006-02-13 Thread Juerd
Luke Palmer skribis 2006-02-13  9:36 (+):
 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


Re: Instance attributes collision

2006-02-13 Thread Luke Palmer
On 2/13/06, Juerd [EMAIL PROTECTED] wrote:
 Luke Palmer skribis 2006-02-13  9:36 (+):
  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


Re: Instance attributes collision

2006-02-13 Thread Luke Palmer
On 2/13/06, Yiyi Hu [EMAIL PROTECTED] 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


Re: Instance attributes collision

2006-02-13 Thread Juerd
Luke Palmer skribis 2006-02-13  9:46 (+):
 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*.


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


Instance attributes collision

2006-02-12 Thread Yiyi Hu
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?

Thanks,
xinming


Re: Instance attributes collision

2006-02-12 Thread chromatic
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