David Storrs
Wed, 13 Jul 2005 14:37:32 -0700
On Jul 13, 2005, at 4:35 PM, chromatic wrote:
On Wed, 2005-07-13 at 16:07 -0400, David Storrs wrote:My understanding is that a Role is an abstract (i.e. cannot be instantiated) blob of methods and, possibly, data. The purpose of a Role is to paste it into a class--in other words, a Role is a not a type, it is a part of a type.Nope, it's a type. What is a type besides a named blob of methods and,possibly, data?
A label that says how the data is stored internally. For example, compare "Int" and "int". The former is a type and a blob of methods and not necessarily abstract. The second is a type, is NOT a blob of methods, and is definitely NOT abstract.
That was part of why I was careful to say "an ***abstract**** [...] blob of methods...." (Emphasis added.)
The point of this is to force the programmer to give a reasonable constraint...when they expect something that Wags, does it need to be a Dog, or will any Animal that can Wag be sufficient? Or are they really looking for absolutely anything that is capable of Wagging?The latter.
Fine. Make them say that, then. Making people think about what they really want is a good idea.
As soon as you require signatures to enforce *how* the arguments fulfilla type constraint, you've violated a principle design goal of roles,namely that it's more important that something fulfills the requirementsof type ("RobotDog understands bark() in the context of Doglike, not Treelike") than that it fulfills the requirements of the type byinheriting from a base class, delegating to a contained object, applyinga role, or whatever other way you can imagine.
That's a reasonable point. However, I wasn't deliberately using 'does Bark' to mean 'has been composed with the role Bark'. I was using it to mean "is able to perform the interface specified by Bark". So, if you prefer, I'll invent a new term: isableto. (Which I think is a lousy choice for the term, but I don't care what color that bike shed is.)
Note that there are two subtly different kinds of type constraints under discussion: the first is what class something is, and the second is what behavior it can exhibit. The two are very slightly different:
multi foo(Dog $x); # Must be of class Dog, or a class that is a descendant of Dog multi foo(Dog $x where { not $x.feral }); # Must be of anonymous class "class Dog (or descendant) with $.feral set to false" multi foo(Dog isableto Bark); # Must be of class Dog (or descendant), and must be able to Bark multi foo(Object isableto Bark); # Absolutely any object so long as it can Bark...how it does that is up for grabs, though.
multi foo( isableto Bark); # Same as previous
The distinction I'm drawing is between pure behavior and behavior
+state. I'm drawing this based on the idea that Roles are not
allowed to have state--that they are pure virtuals, only used for
defining interface. If that is not true, then (A) I apologize for
the wasted bandwidth and (B) I'd like to have it explained what Roles
offer that justifies their existence, since they won't be anything
but a restricted form of a class.
--Dks