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

Reply via email to