Jonathan Lang wrote:
Assuming that I understand the terminology correctly, I'll go further
and say that one of the big differences between roles and subtypes
(using the terms in their perl 6 contexts) is that roles conceptually
operate on intension sets - everything about them is defined in terms
of their set of capabilities - while subtypes (i.e., objects with
"where" clauses) operate on extension sets - they're defined in terms
of the valid set of instances.
You understand the terminology correctly. I'm kind of split
of which approach to favor. I can understand Smylers objection
that the very existence of these two sets and the contradictory
results that set ops produce on them should prevent the usage of
set syntax for type construction. OTOH, I know of nothing else
that conveys the intent as terse.
Incidently, I'm using terms like "supertype", "subtype", "superrole",
"subrole", etc. strictly due to a lack of a better alternative.
"Supertyping" only leads to a larger set of instances because a
parameter that asks for the supertype is willing to accept a subtype
in its stead.
Yes, this is how the argument goes. A supertype constraint allows
more instances to pass the test because the set of requirements is
That's the brittleness: the set of methods that you are permitted to
define in the superrole is restricted to the set of methods in the
role being generalized.
But that makes no sense at all because these are the ones which are
specialized further down in the subtyping chain. There has to be
some extra that the supertype defines for the subtypes.
Since Num doesn't include methods re or im,
an attempt to include either method in a Complex superrole would be an
error according to this approach, or it would involve changing Num to
include methods re and im in the alternative approach.
Then I did read Luke's post wrongly. Sorry.
The write-up that I saw in the original message seems to carry the
implication of the alternative approach (of back-editing the new
methods into the subrole). Note that if you go this route, you really
should allow yourself to define multiple versions of the new method:
one for the superrole, and one for each of the subroles used to define
it. I'd rather not go this route, though.
Hmm, looks like this is exactly where I intent to go. If we detach
method dispatch from the class that in the end provides the method
table for its instances we get the picture that the Complex supertype
creates dispatch targets for &im:(Num) and &im:(Complex) and since
Num <: Complex dispatch goes to the simple 0 returning role default
when called on a Num. So to support supertyping the lookup process
of methods has to scan upwards in the inheritance and role hierarchy
instead of just looking into a table in the class the object is blessed
into. But I think this is how dispatch works, doesn't it? The lookup
result might be cached for efficiency.
Look at it according to the normal flow: if you subtype a role with
read/write capabilities, the new role cannot have fewer rw
capabilities than the role that it's composing has. Reversing this,
if a role does not have a particular rw capability, then a superrole
cannot add it. This is a variation on the "adding methods to the
Well, and of the debate of how to retype an object. I see the .im
method in a position to do the right thing when given the invocant
and the rhs of the assignment. The thing I don't know is how the
syntax looks like. Does one write a STORE block into the method
body? And how is the container involved in the process?
Mind you, once you've defined a supertype, you can freely create new
subtypes of it, and you can add whatever features you want to those
new subtypes, be they lvalue access, new methods, or anything else.
This is unquestioned. But my whole point is to get the Num nicely
embedded in the Complex without touching the Num implementation.
IMHO, the correct way to create an unordered Complex role from a Num
role is to use supertyping to remove the ordering capabilities from
Num, and then use subtyping to add "imaginary component" capabilities
to that. Yes, this means that a simple partial ordering check between
Complex and Num will result in a "no relation" result; but that's a
shortcoming of the type-checking system, not the type definition
Sorry again, the whole point is to get Num <: Complex in the first
place. How else should a subtyping directed dispatch system pick
methods? No relation can also be achieved with a unrelated
implementation of Complex.