All this Haskell programming has opened my eyes to what our multimethod dispatch could be. As we have seen with C<sort>, the dispatch system is a pattern matcher. But it's a pretty terrible one.
I think we should replace our multimethod system with a more general pattern matcher, a "variadic multimethod" system of sorts. Multimethods need to be variadic anyway, because we want pugs's quicksort example to work. Here's my proposal: Inside an argument list, the first mention of a variable introduces its binding. Later arguments require a match. We can now define 'equal': sub equal ($x, $x) { 1 } sub equal ($x, $y) { "" } That's one of the MTOWs at least. The evaluation order of the patterns still needs to be thought out. There are more types of patterns. Types are patterns, and from this we see that following a pattern by a variable binds the variable to whatever matched that pattern. Constants are also patterns. Junctions of patterns are also patterns. Lists of patterns are patterns, as are hashes of patterns. In fact, the last two give us slurpy scalars: sub length () { 0 } sub length (*[ $x, [EMAIL PROTECTED] ]) { 1 + length @rest } And +$name parameters: sub length (*{ name => $name }) { } C<where> constrains a pattern: sub factors ($x where { is_prime($x) }) { $x } ... (The object in question is given as the topic of the where block: sub factors ($x where { .is_prime }) { $x } ... ) There will also be hooks to allow arbitrary pattern objects. # does $x match our pattern? method Pattern::MATCHES ($x) { ... } And now here's the cool part. A type is defined to be a pattern (a 'class' is different, though, but it creates an identically-named type). So instead of definining these multis (I seek to banish the 'multi' keyword, since I seek to banish the idea of an invocant), you could also pretend that they're methods on subtypes. A 'role' is just a collection of methods on a type, a pattern: role ($x where {.is_prime}) { method factors() { $?SELF } } This is exactly equivalent to: sub factors($x where {.is_prime}) { $x } And of course, if you define a role with a name, then it becomes an "abstract type": role Serializable { method serialize() {...} method clone() { restore(.serialize) } } And you have to tell objects that they're Serializeable. Luke