Should roles and classes be merged?
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?
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?
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?
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?)
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