Scope rule pecularities

Josiah Carlson jcarlson at uci.edu
Thu May 13 11:25:55 EDT 2004


 >>The real thing to remember is that Python isn't <insert the language 
 >>you expect Python to behave like>,
 >
 > I think it is reasonable to expect a language to behave consistently.
 >
 > I would like to be able the understand what += does to
 > an object without the need of knowing it is mutable or
 > not.

Well then, that is easy, += does whatever the object says it should do. 
   The only builtin type that is actually modified in place (via +=) are 
lists.  Everything else uses single name rebinding.  Is that a simple 
enough rule, because had you done /any/ sort of critical investigation, 
you would have discovered it yourself.  Your investigation would have 
turned up that immutables behave as they should, and a list's __iadd__ 
method is an alias for its extend method.


 >>>I now expect a and c still to be the same object.
 >>
 >>If 'a' is mutable, and 'a' has the proper __iadd__ operator, then 'a'
 >>and 'c' will be the same object when you are done.  However, integers,
 >>strings, floats,... are immutable, so 'a' and 'c' won't be the same
 >>object in those cases (Python only rebinds objects that are specified,
 >>due to the whole "explicit is better than implicit" Zen).
 >
 > Python does more than enought things in an implicit way.

And automatically rebinding /every/ name that references an object is 
more explicit?  I don't think so.

If all you can say is, "I don't like it, it should be more consistant", 
then I ask, "what would be more consistant?"  Should we keep a list of 
every name that references an object so that functionally, everything is 
passed by reference and can be modified at will?  Should we force 
everything to be mutable, only interning (and making immutable) objects 
used as keys in a dictionary?  Honestly, I don't believe either option 
is a good idea.  Let us look at an example and find out why.

Hmmm, dictionaries.  Dictionaries are hash tables that contain a key and 
value pair.  In order to handle dynamic expansion of the hash table, we 
must keep the key (Python keeps a pointer to the key, it is much faster 
that way).  Right now, only immutables are able to be keys.  Why is this 
so?  Let us imagine that we use a mutable string as a key in a 
dictionary.  Everything is fine and dandy, until we modify the string. 
At that point, in order for the dictionary to stay consistant, we must 
make a copy of that string to keep it as a key.  No big deal, right? 
Wrong.  What if that string were 500k?  500M?  It becomes a big deal.

Similarly, rebinding all names that point to an immutable, when that 
immutable is modified via += is a fool's errand, /especially/ when we 
can use l = 1000000*[0].  According to the rebinding method, all million 
pointers would need to be rebound to the new object, which would be the 
same as making an integer mutable, which has the problem described in 
the previous paragraph.

I think you'll find Python's handling of all immutable values to 
coincide with how C handles single integers (except for the 
pass-by-reference in function calls).


 >>and your expectations are not what
 >>actually happens.  What you think /should/ happen is not what /does/
 >>happen, and I am quite sure it is not what /Guido thinks should happen/.
 >
 > So? Is what Guido thinks should happen above criticism. I think
 > that if what Guido thinks should happen makes the language
 > behave inconsistenly then

No, Guido is not above criticism.  The mistakes he believes he has made 
will be fixed in the 3.0 release.  If you can't wait for it, then 
perhaps you should write the interpreter/compiler for the language you 
want to use.  It seems to be in vogue these days.

  - Josiah



More information about the Python-list mailing list