arnsholt / snake

Not Quite Python
9 stars 1 forks source link

Implement the object model #3

Open arnsholt opened 9 years ago

arnsholt commented 9 years ago

The crux of getting Python's object model right is that the construction foo.bar(args) is not parsed directly as a method invocation. Rather it decomposes into two operations: first an attribute read, followed by the invocation of the value returned from the attribute.

Thus, attribute lookups don't work quite like you might expect. First, the object itself is searched for a member with that name. If it exists, it's returned as is. If it doesn't exist however, the instance's class object is searched for a member with the same name. If it exists and is callable, an instance method (basically lambda *args: meth(_self, *args) with some sugar on top) is created and returned. If the immediate parent class doesn't have that member, the rest of the hierarchy is searched in C3 order.

Predicting what attribute names are valid for a Python object is clearly undecidable in the general case, so an initial implementation should definitely use the HashAttrStore REPR to back objects, since this just lets us assign stuff when they crop up. A more performant implementation may want to do something like a hybrid of P6opaque and HashAttrStore. Similarly, class objects should also use the HashAttrStore REPR, since methods are just data members and they can be assigned willy-nilly.

In conclusion: The challenge is getting attribute lookups on instances and class objects to delegate in the correct way.

arnsholt commented 9 years ago

As discussed with jnthn++ and masak++ (http://irclog.perlgeek.de/perl6/2014-11-19#i_9687055 seqq.), it shouldn't be too impossible.

To make attributes not too slow, compile them to a lookup of the attribute directly first, then guard by checking for null return value. If it's null, fall back to invoking custom attribute-getting code in the metaobject.

This implies two metaobjects, one for instances and one for classes, where both have the same API for attribute lookup (but different logic, obviously). This should be possible.

This probably has to be revisited once we need to implement descriptors though.