Larry Wall wrote: > Dave Whipp wrote: >> Ovid wrote: >> >>> I'd like to see something like this (or whatever the equivalent Perl 6 >>> syntax would be): >>> >>> class PracticalJoke does Bomb does SomeThingElse { >>> method fuse() but overrides { ... } >>> } >>> >>> The "overrides" tells Perl 6 that we're overriding the fuse() method >> > from either Bomb or SomeThingElse (or both). Otherwise, a warning >> > or exception would be useful to prevent me from accidentally overriding >> > needed behavior. >> >> This would also be useful to catch the case where you mistype the >> override method, and so have to go debug why you're still using the >> base-class (or role) version of the method. > > Note we already have syntax that can be applied here: > > supersede method fuse {...} > augment method fuse {...} > > It only remains to spec what those mean... :)
"supersede" already has a meaning with respect to classes; and what I'm thinking of would apply to classes as well as roles; so I'm going to suggest another keyword. How about this: in role composition, "mandate" causes methods to take precedence over other methods with which they would normally conflict, and to conflict with methods that would normally take precedence over them. So: role R1 { mandate method foo { ... } } role R2 { method foo { ... } } class C does R1 does R2 { ... } Normally, the compiler would complain of a conflict between R1 and R2; but because R1::foo is mandated, it wins out. role R { mandate method foo { ... } } class C does R { method foo { ... } } Normally, C::foo would take precedence over R::foo; but because R::foo is mandated, the compiler complains of a conflict between C and R. When two methods have the "mandate" keyword, they are compared to each other as if neither had the keyword. role R { mandate method foo { ... } } class C does R { mandate method foo { ... } } Since both R::foo and C::foo are mandated, C::foo supersedes R::foo. Applying the "mandate" keyword to a role is shorthand for applying it to all of its methods. mandate role R { method foo { ... } method bar { ... } method baz { ... } } is the same as: role R { mandate method foo { ... } mandate method bar { ... } mandate method baz { ... } } This behavior can be overridden by the "suggest" keyword: mandate role R { suggest method foo { ... } method bar { ... } method baz { ... } } is the same as: role R { method foo { ... } mandate method bar { ... } mandate method baz { ... } } That is, every method is either mandated or suggested, and suggested by default. Mandating a role changes the default for its methods, or you could explicitly suggest the role. The latter possibility would allow for a pragma that changes the role's default importance from suggested to mandated. Ovid's distinction between interface and unit of behavior could be managed by this distinction: "suggest role R" is primarily intended as an interface, with behavior being a suggestion only and implicitly overriden by the class; "mandate role R" is primarily intended as a unit of behavior, and overriding its behavior requires that you explicitly supersede it. In Ovid's programs, he might start by saying "use mandate", so that roles operate as units of behavior by default, and can be declared as interfaces by saying "suggest role" instead of "role". Or maybe the pragma declares "interface" as a synonym for "suggest role". (I'd be more comfortable with this if I could think of a comparable synonym for "mandate role"; at that point, you could do away with the pragma - use "role", "suggest role", or "interface" to mean "interface", and use "mandate role" or ??? to mean "unit of behavior".) At this point, you can strengthen the importance of a method (raising it from a suggestion to a mandate); but you cannot weaken it. Thus, interfaces can be composed into units of behavior; but not vice versa: attempting to do so would result in a unit of behavior. I think that the converse _should_ be possible; but I'm not quite sure how it might be done. -- Jonathan "Dataweaver" Lang