On Aug 24, 2005, at 23:34, Sam Ruby wrote:


Leopold Toetsch wrote:

Note that you would then be caching the results of a curried function
call.  This result depends not only on the method string, but also on
the particular object upon which it was invoked.

No the "inner" Parrot_find_method_with_cache just caches the method for
a specific class (obeying C3 method resolution order as in Python).
There is no curried function at that stage.

Where does Parrot_find_method_with_cache get this data?

Remember, in Python, there are no methods, there are only properties.

Above Parrot interface function tries to locate Sub objects in the namespace of the invocant's class and in the MRO of it. When you go back to the PIR translation of your code there is e.g.

  class Foo:
    def g(self,y):

I have translated this to:

.namespace ["Foo"]
.sub g
    .param pmc self

Therefore all the static / default / common "methods" inside Python code would be callable with the plain Parrot method call syntax.

The classname contributes the namespace. The sub declaration creates an entry in that namespace, which is retrievable as:

  func = findglobal "Foo", "g"

And as the namespace is exactly the classname this is exactly what find_method for a "Foo" object does, when trying to locate a method named "g" (I'm omitting here further lookups according to MRO due to other parents). The actual namespace that the classes find_method looks into can further be finetuned with the vtable function VTABLE_namespace_name(interp, class).

Other methods, like the one defined by "f = f", would of course need a fallback to attribute lookup (please can we keep the term attribute, which is also used in CPython) - and not property). Therefore the 'find_method' inside Py code should also consult the attributes of the object (and yes properties for per object overrides).

Well, this is at least my understanding how it could work.


Of course, there is a find_method VTABLE entry, and the implementation
of this function calls __get__ which performs the curry function, per
the Python specifications.

Yes. But currying isn't needed for a plain method call, when the __get__ isn't user defined. Why first curry the function in the first place, create a new curried sub PMC, then during invocation shift arguments, and eventually run it. This isn't the common case. Even if CPython does it like this now (and Python folks are discussing an optimized opcode on pthon-dev), it's not better or more correct - just the result is important. And that works as is now for Parrot method calls.


Does Parrot_find_method_with_cache cache the results of the previous
call to find_method?

It does one dynamic lookup and caches per class/method the result. The cache is invalidated by a store_global (which could influence the dynamic search result).

- Sam Ruby

leo

Reply via email to