
Guido van Rossum wrote:
I've started reading the paper and agree that it's very good!
It's interesting, however, to see how the theory was applied on Python and to establish the fairly easy analogy of the binding model. This analogy proves the good design choices Guido has made, but also reveals some weaknesses or the incompleteness of the current implementation. I hope to discuss this for Python 2 in due time and perhaps settle on a compromise which trades genericity for performance. The naming/binding problem drives the whole implementation logic in Python (objects, classes, scopes, etc.).
I'd like to hear what those weaknesses are in your eyes. I can think of two areas myself: (1) sys.path, $PYTHONPATH etc.; (2) class/instance attributes in the context of subclassing and evolution of the base class.
(2) subsumes (1).
(I don't expect the paper to take a stance on nested scopes.)
But we can. I can't make the time for this right now and I apologize. This subject deserves more attention and I can't describe it quickly, so it has to wait. As I said, in due time ;-). I'm currently overloaded. (In my defense, and Barry will undesrand me very well, I'll say that among othger things I'm reworking the www.inrialpes.fr Web site, which is actually a shame -- now that I'm in charge, come and visit it in a month). Anyway, some quick general notes on what actually exists: Where Python (Guido) really strikes is that almost everything we have at the language level is interpreted as a name. Thus, "sharing can occur". These names are always resolved in some context associated with the object containing the named object. Since all we have is names, the risk of name conflicts is real, especially when half of the contexts against which name resolution occurs are implicit. Therefore, name resolution has to be done in a controlled way (what Guido has successfully tried to provide when designing the language). Simple example:
print o.attr
This says: print the value of an object, whose name "attr" has to be resolved in the context associated with the object "o", this context being explicitely pointed out by a dot "." Another (not so obvious) one:
print 1
This says: print the value of an object, whose name "1" has to be resolved in the current (implicit) context. And this is exactly what happens inside the VM in terms of LOAD_CONST <some internal name, bound in another context, the binding being derived from the resolution of the name "1">, then PRINT_ITEM. If you don't grasp this, try the same example:
a = 1 print a
This says: Resolve the name "1" in the current context (thus we reach the object in question) then assign a new binding ("a" -> the object) in the current context. Then for "print a", see "This says" of the previous example. A valuable thing happens in my last example:
print o.__dict__
This resolves the name "__dict__" in the context associated with the object named "o" (pointed by a dot "."), returning this same context! (or a fraction of it). Whether we have to get a portion of the context or the full context is debatable. It has been felt that with the dynamicity of Python, it's useful to get access to the context, then play with it in a controlled manner. So from here, I (and you) can deduce what happens in terms of naming and binding on function/class/... definitions, on module imports, on attr lookups, on "global" declarations, and so on, and when and where (and hopefully why) we get name conflicts or strange (implicit) name resolutions for nested functions. A last word towards classes: There's no difference between
o = C() # an instance of the class C o.__class__
and
o = 1 o.__class__
I'm prevented to type "1.__class__" only for syntactic reasons, but the context for the resolution of o.__class__ exists. What's missing is for a future mail. Later, -- Vladimir MARANGOZOV | Vladimir.Marangozov@inrialpes.fr http://sirac.inrialpes.fr/~marangoz | tel:(+33-4)76615277 fax:76615252