Should roles and classes be merged?

2005-10-14 Thread Rob Kinyon
In the discussions I've had with Steve, one thing that always
nagged me - what's the difference between a class and a role? I
couldn't fix it in my head why there were two separate concepts.
Steve, yesterday, mentioned to me that in the metamodel that he's got
so far, Class does Role. This means that you can have Class A does
Class B, and it will DWIM. Additionally, Larry has said that he wants
to be able to instantiate a role.

This makes gut-sense to me. A role is really just a class
snippet, complete or not. You can compose these snippets together to
make a larger class. Or, in many cases, you can just instantiate the
snippet and have a viable instance. You can also have an incomplete
snippet, just as you can have an incomplete class. This could be
useful for things like interfaces.

Now, you can have your class inherit from another class, compose
itself from other classes, or both! It's completely up to you. You can
have your roles in an inheritance hierarchy, and it will all just
DWIM.

What this means is that classes and roles both quack, swim, and
lay eggs. They're both just ducks. Given that, there's no need for two
separate concepts in the implementation. It just makes for a more
complex implementation.

I need to stress that I'm not suggesting that the keyword role
be removed. It won't be the first time we have keywords that mean the
same thing, just with a little sugar added. It definitely improves
maintainability to have separate keywords for separate ideas, even if
they're implemented identically.

Thanks,
Rob


Re: Should roles and classes be merged?

2005-10-14 Thread Yuval Kogman
On Fri, Oct 14, 2005 at 09:08:45 -0400, Rob Kinyon wrote:
 couldn't fix it in my head why there were two separate concepts.

The difference between a class and a role is in the eyes of their
consumer - the way in which a class gets new behavior (inheritence,
mixin, or role composition style) is fundamentally the thing that
determines whether the consumed thing is a class or a role.

Ofcourse, to encourage correct use of a consumable unit of behavior,
one can use class or role.

However, there is more to it, conceptually - roles make much more
sense when parametrized over other types, while classes make more
sense unparametrized, due to the way they are used. Last I heard
there only roles were allowed to be parametrized, but there really
isn't any technical difference between classes and roles in this
respect either.

Frankly I think that classes make just as much sense when
parametrized, but i don't really mind parametrizing roles that are
really classes to make anonymous classes. This way it is clear that
there can never be uninstantiatable classes around.

-- 
 ()  Yuval Kogman [EMAIL PROTECTED] 0xEBD27418  perl hacker 
 /\  kung foo master: /me kicks %s on the nose: neeyah!



pgpSXywhAFpZI.pgp
Description: PGP signature


Re: Should roles and classes be merged?

2005-10-14 Thread Larry Wall
On Fri, Oct 14, 2005 at 09:08:45AM -0400, Rob Kinyon wrote:
: What this means is that classes and roles both quack, swim, and
: lay eggs. They're both just ducks. Given that, there's no need for two
: separate concepts in the implementation. It just makes for a more
: complex implementation.

I don't think they'll end up the same, quite.

: I need to stress that I'm not suggesting that the keyword role
: be removed. It won't be the first time we have keywords that mean the
: same thing, just with a little sugar added. It definitely improves
: maintainability to have separate keywords for separate ideas, even if
: they're implemented identically.

Certainly a different keyword can be used to convey a different intent.
And because there's a different intent, we can have different defaults
for them, at minimum.

But I think it goes a little deeper than that.  Not to put too fine
a point on it, classes want to be open, and roles want to be closed.
Let's not forget that the main point of roles is to commit to units
of behavior that can be composed into classes (and other roles)
at compile time.  It's your basic mutable/immutable distinction.
The compiler can rely on immutable values not changing.

Now, we've said you can use a role as if it were a class, but
you do it by generating an anonymous class of the same name.
Er...yeah...something like that...

Going the other direction, you could also use a class as if it
were a role, but only by taking a snapshot of its current value.
If you're planning to modify your base class after that, you'd
better be using inheritance rather than composition, or the derived
class won't see the change to the base class, and that would be
unfortunate.  It's bad enough that you might have to notify all
the existing objects that one of its base classes has been modified.
Doing that notification to objects of classes that have composed roles
with compile-time assumptions would be a nightmare of pessimization.
The first implementation of Perl 6 might not make use of optimizations
based on compile-time composition, but we need to leave that door open.

Generics are somewhat orthogonal to the mutable/immutable distinction,
except that they're a better fit for roles because someone has to
choose when to instantiate them, and they're easier to understand
with early binding rather than late binding.  So another way to view
the role/class distinction is that roles have eager semantics while
classes have lazy semantics.  I expect it's possible to do lazy
generics, but I would put it in the category of hard things that
should be possible.

Do I make myself perfectly muddy?  :-)

Larry


Re: Should roles and classes be merged?

2005-10-14 Thread Rob Kinyon
On 10/14/05, Larry Wall [EMAIL PROTECTED] wrote:
 : I need to stress that I'm not suggesting that the keyword role
 : be removed. It won't be the first time we have keywords that mean the
 : same thing, just with a little sugar added. It definitely improves
 : maintainability to have separate keywords for separate ideas, even if
 : they're implemented identically.

 Certainly a different keyword can be used to convey a different intent.
 And because there's a different intent, we can have different defaults
 for them, at minimum.

 But I think it goes a little deeper than that.  Not to put too fine
 a point on it, classes want to be open, and roles want to be closed.
 Let's not forget that the main point of roles is to commit to units
 of behavior that can be composed into classes (and other roles)
 at compile time.  It's your basic mutable/immutable distinction.
 The compiler can rely on immutable values not changing.

Ok. So, in essence, a role is a class that defaults to being closed
and a class is a role that defaults to being open. Am I rephrasing you
correctly? If so, then they're really the same beast under the hood,
just with different default behaviors.

 Going the other direction, you could also use a class as if it
 were a role, but only by taking a snapshot of its current value.
 If you're planning to modify your base class after that, you'd
 better be using inheritance rather than composition, or the derived
 class won't see the change to the base class, and that would be
 unfortunate.

As you said in the recent class methods thread, it won't be the first
time the programmer would be surprised that the computer did exactly
what it was told to do. If you choose to compose, you're fixing the
behaviors/state at the time of composition, regardless of what happens
after composition. If you choose to inherit, you're not fixing
anything (save when you choose to close).

  It's bad enough that you might have to notify all
 the existing objects that one of its base classes has been modified.
 Doing that notification to objects of classes that have composed roles
 with compile-time assumptions would be a nightmare of pessimization.
 The first implementation of Perl 6 might not make use of optimizations
 based on compile-time composition, but we need to leave that door open.

Why would that notification need to be done? I, the programmer, chose
to compose class A into class B. If I then change class A, I do -not-
want class B to see those changes. Granted, it's an unmaintainable
pile of dreck, but it's MY unmaintainable pile of dreck. And, Perl
shouldn't get in the way of my ability to create piles of dreck. I
think inheritable class methods are horrid, but I do agree that Perl
should give you as much rope as you want.

Rob


Lazy Generics side-bar (was Re: Should roles and classes be merged?)

2005-10-14 Thread Stevan Little

Larry,

On Oct 14, 2005, at 1:28 PM, Larry Wall wrote:

Generics are somewhat orthogonal to the mutable/immutable distinction,
except that they're a better fit for roles because someone has to
choose when to instantiate them, and they're easier to understand
with early binding rather than late binding.  So another way to view
the role/class distinction is that roles have eager semantics while
classes have lazy semantics.  I expect it's possible to do lazy
generics, but I would put it in the category of hard things that
should be possible.


I am not 100% sure what you mean by lazy generics vs. eager  
generics. But in the current metamodel prototype I have implemented,  
what I believe to be, lazy generics. It works like so.


Say we have a generic Unit class, which needs a type (::T) for it's  
value:


  class Unit[::T] {
  has ::T $.value;
  }

Now I am assuming that a class body is a closure (which surely it is)  
and that it usually just gets evaluated right away. What if we defer  
that evaluation?


Lets de-sugar the above example a little:

  my $Unit = sub (::T) {
  class Unit[::T] {
  has ::T $.value;
  }
  };

Now we have not yet actually created any Unit classes yet (generic or  
otherwise). Instead we have a closure which given the right set of  
parameters, can create specific instances of the Unit class which are  
parameterized.


Now we create our Unit[Int] class like this:

  my $unit_int = Unit[Int].new();

Which would be just sugar for this:

  my $unit_int = $Unit.(Int).new();

Again, I am not sure if this is what you mean by lazy generics or not.

Stevan