At 10:28 AM -0600 1/15/03, Garrett Goebel wrote:
Peter Haworth wrote:
 Dan Sugalski wrote:
 > Adriano wrote:
 > >
 > >I think what Jonathan asked for was an operator for
 > >returning a method (as an object) which can be invoked
 > >later with some arguments (or even applied with a
 > >partial list of arguments for currying).
 > >
 > >This would be a lot more useful than a yes-or-no
 > >answer about the existence of a method.
Exactly. 'Yes' might be valid one moment, and invalid the next. Not a very
useful operation... Returning a coderef on the other hand is useful.
Returning a valid coderef isn't often useful, very limiting, and potentially inappropriate for our main targets. The only way they're of any general use is if they just wrap the method invocation again, in which case they're also slower than a plain method call. I have this nasty feeling I'm going to be going over this explanation several times, so I'm going to do it once here and hope for the best.

We are building an OO system for dynamic languages. This means the list of methods that exist for an object may vary over time, it means the list of methods that can be satisfied for an object vary over time, and it means the two sets don't completely overlap. Plus we also have multimethods to contend with, for the unwary

When you invoke a method, like:

foo->bar

One of several things could happen:

1) The bar method somewhere in foo's hierarchy is invoked
2) The bar method for no args is invoked in foo's hierarchy
3) AUTOLOAD, or its moral equivalent, is invoked somewhere in the hierarchy because there is no bar method, so the fallback is used
4) Like #3, only it then creates a bar method
5) We invoke the bar method, which then changes before we can invoke it again

Getting a handle on the real method, then, is potentially wrong in cases 2 and 5, and not possible or really wrong in 3 and 4 (depending on how we do autoloadish things). It's only really correct for case 1.

For user-level code, that's perfectly fine--if you want to write code that is potentially really wrong, there's no problem. (You won't be the first nor, alas, the last) For that reason we should provide a way to get the real handle for a particular invocation, so if you only want it for user code, that's cool, read no further.

For the interpreter's purposes, though, we can't really use it. User code can incorrectly function in the face of mutating back-ends, but the interpreter must behave correctly in all cases. That's where things get more interesting for us.

Yes, I fully want a caching method-invocation layer, so we can do our best to go as fast as possible in the common case. There's a lot of literature on this, and I'm well aware that we need it if we want to have any hope of blazing speed. Doing that right, though, means caching method lookups and trapping symbol table mutations, doing... interesting potential dispatch courtesy of multimethods, and generally getting funky. Static method handles, though, are just of no use for the *interpreter*. User program, sure, interpreter, no way. The languages are just too dynamic for it to be correct. For that we need dynamic handles, and those are much more work.

That's one of the reasons I didn't really address method invocation with objects, as I wasn't quite ready to get into methods yet. (And I'm still not sure how to handle closed classes, or if we even should--perl/ruby/python classes aren't ever closed, though .NET/JVM classes, IIRC, are all entirely closed)
--
Dan

--------------------------------------"it's like this"-------------------
Dan Sugalski even samurai
[EMAIL PROTECTED] have teddy bears and even
teddy bears get drunk


Reply via email to