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