Re: set operations for roles
HaloO, Jonathan Lang wrote: my @array = (0,1,2); # Array of Int @array[3] = "three"; # Array of Int(&)Str Actually, these would be something along the lines of "Array of Int" and "Array of (Int, Int, Int, Str)", respectively. That is, each of @array[0..2] would be of type "Int", while @array[3] would be of type "Str". Oh, no. Array of (Int,Int,Int,Str) would prescribe every single entry to be of the type (Int,Int,Int,Str) and I believe you need to write Seq[Int,Int,Int,Str]. @array itself would be of type "Array" (which, without any further qualifiers, is equivalent to "Array of Any"). If you must force a more restrictive type on @array, go with "Array of (Int | Str)" (yes, I do mean "|", not "(|)"; it's a type-matching issue, not a container-construction issue.) Which is another argument for choosing '(|)' to mean supertype in role combination. Regards, TSa. --
Re: set operations for roles
Jonathan Lang schreef: > (&) and (|) would actually reflect your intuition regarding the > capabilities of the result, in that a role arrived at by means of (&) > would provide fewer options than the individual roles used to create > it, while a role arrived at by means of (|) would provide more > options. OK, I am glad I asked about "sure" and that it is out of the way (for) now. -- Groet, Ruud
Re: set operations for roles
HaloO, Jonathan Lang wrote: BTW, are the ASCII equivalents spelled (<), (>) and (in)? I'd hope that they'd be something like '(<)', '(>)', and 'in'; only use parentheses when neccessary. Likewise, I'd want the "relative complement" operator to be '-', not '(-)'. Funny. I would have hoped that the parens unequivocally indicate set operations. The set difference should be (-) on the basis that numeric minus should subtract their cardinalities much like it does for arrays and hashes. Regards, TSa. --
Re: set operations for roles
TSa wrote: Jonathan Lang wrote: > OK. My main dog in this race is the idea of defining new roles > through the concepts of the intersection or difference between > existing roles Note that you should not call these 'intersection type' because this term is used for the union of role interfaces. It is? Where? I can't find it in any of the Synopses. That is the typist intersects the extension sets of objects doing the roles that are combined. IOW, set operations for roles could also be defined the other way around. If that solves the perceptive dissonance of a typical Perl programmer that Larry mentioned, I don't know. I think that defining the union of role interfaces as an "intersection" would only lead to confusion. Keep things clear: "A(&)B" is the intersection of A and B, and includes in its interface only those elements that are common to both A's and B's interfaces; "A(|)B" is the union of A and B, and includes in its interface everything in A's interface and everything in B's interface. "A-B" is the difference of A and B, and includes in its interface everything in A's interface that isn't in B's interface. > And yes, this "roles as sets" paradigm would presumably mean that you > could examine roles using '⊂', '⊃', '∈', and so on. Given the > semantic aspect of roles, I don't think that I'd go along with saying > that 'A ⊃ B' is equivalent to 'A.does(B)' - although I _would_ agree > that if 'A.does(B)' then 'A ⊃ B'. Rather, I'd think of 'A ⊃ B' as > being the means that one would use for duck-typing, if one really > wanted to (presuming that one can mess with how perl 6 does > type-checking). I guess up to now it is undefined how structural and how nominal the Perl 6 type system is. It's not explicitly stated, as far as I can see; but it does seem to be implied that type-checking makes use of .does(), and that .does() is essentially nominal (for a sufficiently broad definition of "name"). But I agree that when a role A says that it does B that the type system should check if A ⊃ B. I disagree. It's implicit that if A.does(B), then A ⊃ B; so checking the latter as well as the former would be redundant. Meanwhile, the converse is _not_ true: it is quite possible for A ⊃ B to be true while A.does(B) is false. Using something closer to a nominal approach allows the role's "name" to convey the semantics, something that a strictly interface comparison would be unable to do. Note that union interfaces might need some merging of signatures as I tried to argue elsewhere. The only merging of signatures that I'd want to see would be to drop them entirely in the case of a collision of non-multi methods. Also, we might allow the subrole to change signatures in accordance with the intended subtype relation. Note that perl 6 doesn't speak of subroles; and while it _does_ speak of subtypes, it means something entirely different by the term than what type theory means by it: in perl 6, a subtype is a way of placing restrictions on the acceptable values that an object can have. In the sense that it limits what a type can do, it's more akin to what you'd call a supertype. -- Jonathan "Dataweaver" Lang
Re: set operations for roles
HaloO, Jonathan Lang wrote: If we make a point of highlighting the "set operations" perspective You know that there are two sets involved. So which one do you mean? and avoiding traditional type theory terminology (which, as Larry pointed out and TSa demonstrated, is very much inside out from how most people think), we can avoid most of the confusion you're concerned about. Well, the type theory terminology has it all. You just have to be careful what you pick and how you combine the terms. "Sub" and "super" be it in class, role or type connotate an order that in fact is there as a partial order or preferably as a lattice. The rest is about choosing a syntax. I for my part can live happily with whatever flipping of (&) and (|) we settle on as long as I know to which set they apply. That being said I would think that prior art dictates (&) as meaning subtype creation. Which puts it in line with & for the all junction and && as logical connective. Note that the counterintuitive notation for pre-composed roles using | is gone. It still exists in the signatures, though. Regards, TSa. --
Re: set operations for roles
TSa <[EMAIL PROTECTED]> wrote: I strongly agree. Having a language that allows supertying has novelty. But I think that union is not there for completion but as integral part when it comes to defining a type lattice which I still believe is the most practical approach to typing. This includes computed types, that is "artificial" nodes in the lattice. These intermediate types are usually produced during type checking and automatic program reasoning. Think e.g. of the type of an Array: my @array = (0,1,2); # Array of Int @array[3] = "three"; # Array of Int(&)Str Actually, these would be something along the lines of "Array of Int" and "Array of (Int, Int, Int, Str)", respectively. That is, each of @array[0..2] would be of type "Int", while @array[3] would be of type "Str". @array itself would be of type "Array" (which, without any further qualifiers, is equivalent to "Array of Any"). If you must force a more restrictive type on @array, go with "Array of (Int | Str)" (yes, I do mean "|", not "(|)"; it's a type-matching issue, not a container-construction issue.) > And yes, this "roles as sets" paradigm would presumably mean that you > could examine roles using '⊂', '⊃', '∈', and so on. BTW, are the ASCII equivalents spelled (<), (>) and (in)? I'd hope that they'd be something like '(<)', '(>)', and 'in'; only use parentheses when neccessary. Likewise, I'd want the "relative complement" operator to be '-', not '(-)'. -- Jonathan "Dataweaver" Lang
Re: set operations for roles
Smylers wrote: TSa writes: > Ruud H.G. van Tol wrote: > > TSa schreef: > > > A(|)B produces a subtype of A and B, and that A(&)B produces a > > > supertype > > > > Are you sure? > > Very sure ;) In which case that provides a handy example supporting Larry's suggestion that this is confusing, with some people expecting it to work exactly opposite to how it does. It's a terminology issue. The OO terms "subclass" and "superclass" are counterintuitive, in that a "superclass" is more limited than the "subclass" that is derived from it - that is, the "subclass" provides a superset of the elements of the "superclass". I have studiously avoided using that terminology for this very reason. Well, that and the fact that we're talking about roles here, not classes; and conceptually, roles are supposed to be more egalitarian than classes - "super-role" and "sub-role" would carry too much of a hierarchal connotation for what roles are supposed to be. (&) and (|) would actually reflect your intuition regarding the capabilities of the result, in that a role arrived at by means of (&) would provide fewer options than the individual roles used to create it, while a role arrived at by means of (|) would provide more options. It doesn't really matter which way is right -- merely having some people on each side, all naturally deriving what makes sense to them -- shows that implementing this would cause much confusion. I'll have to differ from you here. We (the language designers) get to choose how the concepts get presented, and presentation is everything (or pretty darn close). If we make a point of highlighting the "set operations" perspective and avoiding traditional type theory terminology (which, as Larry pointed out and TSa demonstrated, is very much inside out from how most people think), we can avoid most of the confusion you're concerned about. -- Jonathan "Dataweaver" Lang
Re: set operations for roles
HaloO, Smylers wrote: In which case that provides a handy example supporting Larry's suggestion that this is confusing, with some people expecting it to work exactly opposite to how it does. So the mere fact that there are two sets involved rules out the set operators as well? It doesn't really matter which way is right -- merely having some people on each side, all naturally deriving what makes sense to them -- shows that implementing this would cause much confusion. Better suggestions? Other than just writing one or the other in the spec, I mean. I would opt for A(&)B producing the subtype on the footing that this is usually called an intersection type, even though the interfaces are merged. Regards, TSa. --
Re: set operations for roles
TSa writes: > Ruud H.G. van Tol wrote: > > > TSa schreef: > > > > > A(|)B produces a subtype of A and B, and that A(&)B produces a > > > supertype > > > > Are you sure? > > Very sure ;) In which case that provides a handy example supporting Larry's suggestion that this is confusing, with some people expecting it to work exactly opposite to how it does. It doesn't really matter which way is right -- merely having some people on each side, all naturally deriving what makes sense to them -- shows that implementing this would cause much confusion. Smylers
Re: set operations for roles
HaloO, Ruud H.G. van Tol wrote: TSa schreef: A(|)B produces a subtype of A and B, and that A(&)B produces a supertype Are you sure? Very sure ;) In record subtyping a record is a mapping of labels to types. In Perl 6 speak this is what a package does. One record type is a subytpe if it has a superset of the label set and the types of the common labels are subtypes. This record is the intension set of types. When it grows the "number" of objects in the extension set decreases. The limiting cases are the universal set Any that has the empty intension set and Undef or Whatever with the universal intension set but no defined instances. I see "&" as "limiting; sub" and "|" as "enlarging; super". To me, "&" is connected to multiplication (and inproduct, statistics, fuzzy logic), and "|" to addition (and outproduct). As I just wrote elsewhere this is the extensional view of the sets underlying types. The extension of Bool e.g. is {0,1} and that of Int is {...,-2,-1,0,1,2,...} from which one argues that Bool is a subtype of Int and that Bool(&)Int (=) Bool. On the interface side of things Bool has to support all methods that Int has, e.g. +, -, *, and /. Note that both types are not closed under these operations: 1 + 1 == 2, 5/4 == 1.25. Bool adds logical operators like && and || to the intension set. Regards, TSa. --
Re: set operations for roles
TSa schreef: > A(|)B produces a subtype of A and B, and that A(&)B > produces a supertype Are you sure? I see "&" as "limiting; sub" and "|" as "enlarging; super". To me, "&" is connected to multiplication (and inproduct, statistics, fuzzy logic), and "|" to addition (and outproduct). $ perl -we 'printf "0x%02X\n", 0x0E & 0x33' 0x02 $ perl5 -we 'printf "0x%02X\n", 0x0E | 0x33' 0x3F -- Groet, Ruud Oops, I think I found a bug in sprintf: $ perl5 -we 'printf "%#04X\n", 15' 0X0F which AFAIK should print 0x0F, so with a lowercase x.
Re: set operations for roles
HaloO, Jonathan Lang wrote: > OK. My main dog in this race is the idea of defining new roles > through the concepts of the intersection or difference between > existing roles Note that you should not call these 'intersection type' because this term is used for the union of role interfaces. That is the typist intersects the extension sets of objects doing the roles that are combined. IOW, set operations for roles could also be defined the other way around. If that solves the perceptive dissonance of a typical Perl programmer that Larry mentioned, I don't know. > And yes, this "roles as sets" paradigm would presumably mean that you > could examine roles using '⊂', '⊃', '∈', and so on. Given the > semantic aspect of roles, I don't think that I'd go along with saying > that 'A ⊃ B' is equivalent to 'A.does(B)' - although I _would_ agree > that if 'A.does(B)' then 'A ⊃ B'. Rather, I'd think of 'A ⊃ B' as > being the means that one would use for duck-typing, if one really > wanted to (presuming that one can mess with how perl 6 does > type-checking). I guess up to now it is undefined how structural and how nominal the Perl 6 type system is. But I agree that when a role A says that it does B that the type system should check if A ⊃ B. I believe that it should be possible to fill a node in the type lattice with a named role precisely to catch dispatches to this intersection, union or another combination interface. Or you instanciate parametric roles for the same purpose. Note that union interfaces might need some merging of signatures as I tried to argue elsewhere. Also, we might allow the subrole to change signatures in accordance with the intended subtype relation. Regards, TSa. --
Re: set operations for roles
HaloO, Jonathan Lang wrote: > OK. My main dog in this race is the idea of defining new roles > through the concepts of the intersection or difference between > existing roles (even the union was thrown in there mainly for the sake > of completion), with the consequent extension of the type system in > the opposite direction from the usual one (toward the more general); I strongly agree. Having a language that allows supertying has novelty. But I think that union is not there for completion but as integral part when it comes to defining a type lattice which I still believe is the most practical approach to typing. This includes computed types, that is "artificial" nodes in the lattice. These intermediate types are usually produced during type checking and automatic program reasoning. Think e.g. of the type of an Array: my @array = (0,1,2); # Array of Int @array[3] = "three"; # Array of Int(&)Str This Int(&)Str type might actually be Item. The flattened |@array has type Seq[Int,Int,Int,Str] but the unflattend array should say something that is applicable to all its contents. The array might actually maintain this content type at runtime. > And yes, this "roles as sets" paradigm would presumably mean that you > could examine roles using '⊂', '⊃', '∈', and so on. BTW, are the ASCII equivalents spelled (<), (>) and (in)? Regards, --
Re: set operations for roles
HaloO, Larry Wall wrote: > I now think it's a bad idea to overload | or & to do type construction, Is it then a god idea to overload the set operations? At least the type constructions are set theoretic on the intension set of the roles. > especially since the tendency is to define them backwards from the > operational viewpoint that most Perl programmers will take. Can you give an example how these directions collide? Is it the fact that A(|)B produces a subtype of A and B, and that A(&)B produces a supertype? I can imagine that 'does A&B' could be read as doing both interfaces. BTW, what is set complement? Is it (!)? Regards, TSa. --
Re: set operations for roles
Larry Wall wrote: Anyway, I think the type constructors need to avoid overloading the logic operators. Perl 6 is an operator-rich language because that contributes to long-term clarity despite the short-term confusion. OK. My main dog in this race is the idea of defining new roles through the concepts of the intersection or difference between existing roles (even the union was thrown in there mainly for the sake of completion), with the consequent extension of the type system in the opposite direction from the usual one (toward the more general); the exact syntax used for this is less of an issue, as long as it is straightforward and simple. Given that the set analogy is exactly what I'm using, I'd be fine using the Set operators (presumably '\xAD\xFC' and '\xAD\xFB') and their ASCII workarounds ('(|)' and '(&)'?) instead of '|' and '&'. Presumably, '-' is still the "difference of Sets" operator. And yes, this "roles as sets" paradigm would presumably mean that you could examine roles using '⊂', '⊃', '∈', and so on. Given the semantic aspect of roles, I don't think that I'd go along with saying that 'A ⊃ B' is equivalent to 'A.does(B)' - although I _would_ agree that if 'A.does(B)' then 'A ⊃ B'. Rather, I'd think of 'A ⊃ B' as being the means that one would use for duck-typing, if one really wanted to (presuming that one can mess with how perl 6 does type-checking). Likewise, 'm ∈ R' will match if 'R.can(m)'; but the definition of 'element' might be broader than just methods. -- Jonathan "Dataweaver" Lang
Re: set operations for roles
On Fri, Oct 20, 2006 at 09:10:12AM -0700, Jonathan Lang wrote: : TSa wrote: : >Here is yet another idea to go with the two lattice operations: : > : > /\ meet also: infimum, intersection, glb (greatest lower bound) : > \/ join also: supremum, union,lub (least upper bound) : : I have to admit: if it turns out that '&' and '|' can't be used for : 'intersection' and 'union', '/\' and '\/' wouldn't be the worst : choices to replace them. But I'd like to verify that we can't use : what we currently have first, before we go changing things. I think we should reserve | and & for matching predicates (read: signatures and where clauses) rather than type construction. We have to remember that type theory is completely inside-out to the way most Perl programmers think. Type theory is all about Platonic objects and how you go about constructing such abstractions in the abstract. Most people don't want to think on that level, and are quite willing to delegate the high-powered abstractions to someone else. Therefore I'd like these to be illegal: subset X of Y | Z; subset X of Y & Z; subset X of Y ^ Z; and need to be written more like: subset X of Any where Y | Z; subset X of Any where Y & Z; subset X of Any where Y ^ Z; I now think it's a bad idea to overload | or & to do type construction, especially since the tendency is to define them backwards from the operational viewpoint that most Perl programmers will take. : >and also read nice as english words: : > : > role J joins A, B, C; # same as role J does A \/ B \/ C : > role M meets A, B, C; # same as role M does A /\ B /\ C : : I'm less enthusiastic about this, though: perl already uses 'join' for : list concatenation. We can negotiate the color of the bikeshed over time. I don't personally have a problem with meets and joins, and while you might think that \/ makes it impossible to write [\/] to get a reducing divide, that's not an operator you'd likely want anyway. But one of the basic underlying principles of Perl 6 is that we don't have to overload different operators in a confusing way anymore. \/ should probably be the ASCII workaround for ∨ while /\ is the ASCII for ∧. And at one point @Larry reserved all the parenthesized operators for the ASCII workarounds for set operators. Anyway, I think the type constructors need to avoid overloading the logic operators. Perl 6 is an operator-rich language because that contributes to long-term clarity despite the short-term confusion. Larry
Re: set operations for roles
TSa wrote: Here is yet another idea to go with the two lattice operations: /\ meet also: infimum, intersection, glb (greatest lower bound) \/ join also: supremum, union,lub (least upper bound) I have to admit: if it turns out that '&' and '|' can't be used for 'intersection' and 'union', '/\' and '\/' wouldn't be the worst choices to replace them. But I'd like to verify that we can't use what we currently have first, before we go changing things. and also read nice as english words: role J joins A, B, C; # same as role J does A \/ B \/ C role M meets A, B, C; # same as role M does A /\ B /\ C I'm less enthusiastic about this, though: perl already uses 'join' for list concatenation. -- Jonathan "Dataweaver" Lang
Re: set operations for roles
TSa wrote: Jonathan Lang wrote: > In short, R3 isn't neccessarily a subset of A; it's a superset of A & > B. In a partial ordering graph, there's no reliable ordering between > R3 and A. > > The standard syntax for creating roles can't reliably produce a subset > of an existing role, because it always allows you to add to it. Yes, but I was conjecturing that the additions to A&B are pushed down to A and B such that their intension sets remain strict supersets of A&B. I know; but as you pointed out, a single undefined method brought in this way would break every existing class that composes A or B. Besides, there's the principle of the matter: creating a new role should not change the behavior of existing roles. Admittedly, I'm bending that rule when I suggest that A should get A&B added to its list of roles when A&B is created; but I'm not breaking it, because A&B won't have anything in it that A doesn't already have, and A will uniformly override any behaviors that A&B might provide. The _only_ thing that this change does is to let A match A&B for type-checking purposes. But letting R3 backend new methods into A _does_ change A's behavior: it now has methods that it didn't used to have. This can lead to a more subtle version of the yadda-yadda problem that you pointed out: if someone has a routine that depends on a failure occurring if A.m is called, then the routine will stop working as expected if you backend .m into A via R3. > The only problem that might crop up is the use of 'A | B' in > signatures to mean 'can match any of A, B' - that is: in signatures, > 'A | B' refers to the junctive operator; while in the above proposal, > 'A | B' refers to the set union operator. Different semantics. In fact if we decide to specify a role combination syntax then it should be the same everywhere. Agreed - but we're not talking about role combination syntax in both places. In signatures, we're talking about a conjunction of two distinct roles, which is not the same as any sort of combined role (union or intersection). In particular, the conjunction treats each role as an atomic unit, while unions and intersections deal with their elements. -- Jonathan "Dataweaver" Lang
Re: set operations for roles
HaloO, I wrote: Yes, but I was conjecturing that the additions to A&B are pushed down to A and B such that their intension sets remain strict supersets of A&B. Think of the Complex example that might read role Complex does Num & !Comparable { method im { return 0; } method re { return self as Num } # a no-op for Num } class Complex does Complex { has $.re; # accessor overwrites role method has $.im; # accessor overwrites role method } Apart from the fact that the role and the class compete for the same name slot this looks like what you need to make Num applicable wherever a Complex is expected: module A { use Complex; Num $a; say $a.im; # statically type correct, prints 0 } module B { Num $b; say $b.im; # syntactically admissible, but produces runtime error } Actually the 'self as Num' should return the self type ::?CLASS to preserve as much type information as possible. Hmm, could we get the keyword Self for that? Have a nice weekend, TSa. --
Re: set operations for roles
HaloO, I wrote: In fact if we decide to specify a role combination syntax then it should be the same everywhere. That means in a signature A|B would require a more specific type and pure A or B wouldn't be admissible. To get the old meaning of | you have to write A&B or perhaps the juxtaposition which currently means what A|B should mean. Alternatively the meaning of the role combination A&B could be defined to mean the union and A|B the intersection. Here is yet another idea to go with the two lattice operations: /\ meet also: infimum, intersection, glb (greatest lower bound) \/ join also: supremum, union,lub (least upper bound) These have nice graphical mnemonics meet={x} /\ / \ /\ A={a,x} B={b,x} \/ \ / \/ join={a,b,x} and also read nice as english words: role J joins A, B, C; # same as role J does A \/ B \/ C role M meets A, B, C; # same as role M does A /\ B /\ C Comments? --
Re: set operations for roles
HaloO, Jonathan Lang wrote: In short, R3 isn't neccessarily a subset of A; it's a superset of A & B. In a partial ordering graph, there's no reliable ordering between R3 and A. The standard syntax for creating roles can't reliably produce a subset of an existing role, because it always allows you to add to it. Yes, but I was conjecturing that the additions to A&B are pushed down to A and B such that their intension sets remain strict supersets of A&B. The only problem that might crop up is the use of 'A | B' in signatures to mean 'can match any of A, B' - that is: in signatures, 'A | B' refers to the junctive operator; while in the above proposal, 'A | B' refers to the set union operator. Different semantics. In fact if we decide to specify a role combination syntax then it should be the same everywhere. That means in a signature A|B would require a more specific type and pure A or B wouldn't be admissible. To get the old meaning of | you have to write A&B or perhaps the juxtaposition which currently means what A|B should mean. Alternatively the meaning of the role combination A&B could be defined to mean the union and A|B the intersection. Regards, TSa. --
Re: set operations for roles
TSa wrote: Jonathan Lang wrote: >role R3 does A & B { ... } >R3.does(A) # false: R3 can't neccessarily do everything that A can. >A.does(R3) # false: A can't neccessarily do everything that R3 can. That last one should be true. Role R3 contains the things that A and B have in common. Hence each of them has everything that R3 has. The '...' above isn't the yadda-yadda operator; it's a standin for whatever gets declared in R3. Which leads directly to... > And because you have the ability to add methods to R3 that aren't in A > or B, you can't make use of the fact that A & B is a subset of A for > type-checking purposes. The really funny thing is what can be written into the body of role R3. Should it be forbidden to introduce new methods? Or should new methods automatically enter into A and B? The latter would be more useful but then roles become somewhat open like classes because code that did not typecheck before the superrole creation suddenly typechecks after it. Or if the role R3 adds a yada method that propagates down the composition chains, classes might retroactively fail to compile! In short, R3 isn't neccessarily a subset of A; it's a superset of A & B. In a partial ordering graph, there's no reliable ordering between R3 and A. The standard syntax for creating roles can't reliably produce a subset of an existing role, because it always allows you to add to it. That's why I suggested the idea of binding a role name to a set operation: with 'role Foo ::= A & B', Foo is a subset of A, because Foo is 'A & B', and 'A & B' is a subset of A. In addition, this syntax doesn't rely on the 'does' keyword, so there's no implication that the LHS must be a semantic superset of the RHS. Also, there's no danger of overriding a yadda-yadda in A: the only way to bring your own definitions into Foo would be to use an anonymous role as one of the roles on the RHS: either that role gets brought in via '&' (in which case only those methods that are common to A and the anonymous role will end up in Foo, and thus will be overridden by A), or it gets brought in via '|' (in which case Foo is no longer a subset of A, and 'A.does(Foo)' will be false). In fact, role Foo does A does B { ... } can be thought of as being semantically equivalent to role Foo ::= (A | B) | role { ... } The only problem that might crop up is the use of 'A | B' in signatures to mean 'can match any of A, B' - that is: in signatures, 'A | B' refers to the junctive operator; while in the above proposal, 'A | B' refers to the set union operator. Different semantics. -- Jonathan "Dataweaver" Lang
Re: set operations for roles
HaloO, Jonathan Lang wrote: role R3 does A & B { ... } R3.does(A) # false: R3 can't neccessarily do everything that A can. A.does(R3) # false: A can't neccessarily do everything that R3 can. That last one should be true. Role R3 contains the things that A and B have in common. Hence each of them has everything that R3 has. And because you have the ability to add methods to R3 that aren't in A or B, you can't make use of the fact that A & B is a subset of A for type-checking purposes. The really funny thing is what can be written into the body of role R3. Should it be forbidden to introduce new methods? Or should new methods automatically enter into A and B? The latter would be more useful but then roles become somewhat open like classes because code that did not typecheck before the superrole creation suddenly typechecks after it. Or if the role R3 adds a yada method that propagates down the composition chains, classes might retroactively fail to compile! Regards, TSa. --