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 fulfill
a type constraint, you've violated a principle design goal of roles,
namely that it's more important that something fulfills the requirements
of type ("RobotDog understands bark() in the context of Doglike, not
Treelike") than that it fulfills the requirements of the type by
inheriting from a base class, delegating to a contained object, applying
a 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.


Reply via email to