On Wed, Jan 15, 2003 at 01:00:59AM -0500, Dan Sugalski wrote: > At 8:53 PM -0800 1/14/03, 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. > > I thought about this--it's what the find_method vtable method was for > in the first place. Unfortunately, as was pointed out to me, there's > no good way to cache the result, since it could potentially be wrong > by the time the method is actually called. > > We could potentially get around this if we put in place a > notification framework to invalidate these method handles, but that > means we have to have a fair amount of infrastructure in place to do > that. (Though, honestly, I do really like the idea, as it means we > can be faster by default and just pay the price when things change, > but there's that pesky code that needs writing and systems that need > designing to support it...) How much infrastructure do you need? I thought perl5 cached method lookup, but had a global (per interpreter) generation count, which went up by one every time you (re)defined a method. So for parrot you return a "thingy" that is initially implemented as the direct pointer, a generation count, plus enough other stuff to redo the search. If at the time of calling the generation count is the same, wehay, go for it. Otherwise redo the search there and then, and update. Later on you can add in the notify system, if that's faster. (It may well be, as at that point the pointer will always be valid, even if it's now pointing to some placeholder bytecode that just throws an exception if called.) Hmm. That's a cheat idea. You could keep track of all these "thingies", and make sure the jump pointer was always valid. You just arrange that it is replaced with a pointer into a relookup routine every time something "relevant" gets redefined. (Initially a global counter, but it can get more specialised later). That trades faster call speed each time (because the pointer is now always valid, so you never need to check the generation count at each call) for more maintenance time for each method redefine. Although in turn you could then maintain you backpointers to all the "thingies" in two sets - ones that are currently pointing to the "lookup" code, and ones that point to real methods. Every time the "world" is updated with code (re)definition you convert all the real methods to point to the "lookup" code. Every time a "lookup" code routine is called it finds the real method, and moves itself back to the the real set. This would actually let you defer the method lookup - when you create one of these pointers it's actually lazy, pointing to the "lookup" code, and the lookup is really only done the first time you call it. Am I rambling too much? Nicholas Clark