From: Charles Oliver Nutter Date: 2007-12-22T21:21:05+09:00 Subject: Re: Matz says namespaces are too hard to implement - why? 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