The Real Problem With Roles

Ovid on 2009-07-02T13:47:33

Inheritance, as most of us know, is rather problematic. Specifically, it's been around since 1967 and for the past 42 years, people have been arguing about how to do it right. Some OO languages don't have inheritance (Self, Javascript). Some languages don't have multiple inheritance (C#, Ruby). Some languages have multiple inheritance with many safeguards (Eiffel) or none (Perl). Some languages just do strange things with inheritance (BETA). Even very experienced OO developers focusing on a single language will argue vociferously about whether or not a design has been done correctly (do you really give a damn about strict equivalence in overridden methods?)

The problem is ultimately that classes fulfill conflicting needs. As an agent of responsibility, a class needs to do everything a class needs to do. That sounds like a stupid tautology, but what it means is that as systems grow, classes grow. Thus, classes tend to get larger. Unfortunately, as agents of code reuse -- via inheritance or delegation -- classes should be smaller. How many times have you seen (or written) code which inherits from something because it needs one or two methods but you're pulling in a lot of extra behavior which you don't need?

This responsibility/reuse tension which leads to classes wanting to be both larger and smaller at the same time is much of the reason why inheritance has proven so problematic. Interfaces in Java and C#, along with mixins in Ruby and other languages were an attempt to decouple the responsibility and reuse needs of classes, but they've all had their problems. Roles seem to handle the decoupling of responsilibity and reuse quite nicely, but some of you may have noticed some of the disagreements that I and others have had about the proper use of roles. Why is that?

Ultimately, the disagreement boiled down to the fact that -- like inheritance -- roles serve more than one master. Roles provide behavior and roles provide an interface. Are we faced with another 40 years of arguing because we've again tried to shoehorn too much into one thing? I don't think this need be the case as, unlike classes, the different things the roles provide aren't necessarily antagonistic, but it would be nice if the different parties sat down and tried to come up with a strategy (syntax?) for implementing roles which cleanly addresses these disparate needs. Otherwise, there really will another 40 years of arguing.


JavaScript doesn't have inheritance?

btilly on 2009-07-02T16:57:58

Suppose that object A is object B's prototype and object B is object C's prototype and you add a method to A. Then C can call that method.

This sure looks like inheritance to me!

Re:JavaScript doesn't have inheritance?

perigrin on 2009-07-02T17:26:03

That was my first thought too but *technically* C is a clone of B which is a clone of A, so there is no inheritance. Wikipedia's page on prototype programming (http://en.wikipedia.org/wiki/Prototype-based_programming) helped clarify it for me.

Re:JavaScript doesn't have inheritance?

btilly on 2009-07-02T18:51:24

Sorry, but your technicality is simply wrong. If C was simply a clone of B then after the cloning operation B and C would be separate but equal. But if you create C then add properties to B, C will see those new properties. The converse is not true, new properties added to C are not visible to B. The relationship between an object and its prototype in JavaScript is not a straightforward cloning operation. Instead the newly created object (ahem) inherits properties from the prototype, which may in turn have inherited them from its prototype.

JavaScript, The Definitive Guide explains this in some detail and uses the word "inheritance" for it.

If that is not formal enough for you, go look at the official spec and read through that. Page 3, paragraph paragraph 2 starts with the statement, "ECMAScript supports prototype-based inheritance." (Emphasis in original.) You're going to have a difficult time convincing me that what JavaScript does shouldn't be called inheritance when it is called that in its own official specification! Certainly you won't do it by pointing me at a Wikipedia article which says, Example of true prototypal inheritance style in javascript.