Robert Klemme wrote:
> Ultimately Matz will be the one who is able to answer this properly.  My 
> gut guess is that - besides the issues you mentioned - performance is a 
> critical issue.  Method lookups are so ubiquitous that everything that 
> slows them down should be limited as far as possible.  And method lookup 
> will certainly suffer because the set of allowed methods is no longer 
> determined by a class but also by a location in the code where a method 
> is invoked.  Especially in the light of nesting these selector 
> namespaces lookups will become complex and potentially slow.

Or perhaps, the various implementers will be able to answer this 
properly as well :)

So here's a long answer:

Selector namespaces would be difficult to implement largely because of 
how method dispatch works. Currently, the metaclass of the target object 
is 100% in control. It decides which method will be called in all cases, 
and the caller is not able to influence that selection process in any 
way. So we have to monkey patch the actual metaclass to have new 
behavior show up for all future calls, with the down side of course 
being that new behavior shows up for all future calls...you can't choose 
that some paths see new behavior and some see old.

Groovy is an example of a modern language that supports selector 
namespaces, which they call Categories. Categories allow you to apply a 
set of metaclass changes to one (or more?) class on a specific thread 
within a specific scope. So you can add behavior to String for a block 
of code and all code it calls, and when the block finishes the behavior 
disappears.

And it's dog slow, even compared to normal non-Category Groovy calls 
which aren't particularly fast to begin with.

The way it's implemented in Groovy leverages the fact that all 
invocations in Groovy go first to an intermediary that decides whether 
the target object's metaclass should have the last say or not. If a 
Category is in play, all such intermediaries will allow the Category to 
have first grab at method invocation, at which time they can pretend the 
target metaclass has the new behavior. Otherwise, calls pass straight 
through to the metaclass.

The problem with this is that when you're *not* using a Category, you 
still have to constantly check for each invocation whether a Category 
has been installed. Check, check, check, check, check, check...wasting 
cycles. It also adds multiple additional layers into method invocation 
when you *are* in a Category, since it stacks all the Category logic on 
top of the already heavy method invocation logic.

If not for Categories, no intermediary would be needed, and no checks 
would be needed.

I'd expect similar semantics in Ruby, since non-thread-local namespaces 
would be almost worthless (threads would see behavior on types change 
forward and back at arbitrary times), and as a result similar 
performance implications. Even worse, it would require shoehorning an 
intermediary into the Ruby call path, further slowing it down and 
complicating optimization by VMs like the JVM and CLR. And it would add 
in all the same checks, since every call would have to check whether a 
namespace has been installed before proceeding.

- Charlie