variable declaration

Nick Coghlan ncoghlan at iinet.net.au
Sat Feb 5 11:26:11 EST 2005


Alexander Zatvornitskiy wrote:
> You wrote about "substantial cost" of var declarations. Yes, you are write. But
> think about the cost of lack of var declarations. Compare time that programmer
> will waste on search for the reason of bug caused by such typo, plus time what
> programmer will waste while remembering exact variable name.

This is a problem better solved through a decent editor with code completion 
than through redundant variable declarations, which waste *far* more programmer 
time than typos do.

The *only* time the typo is a potential problem is if a variable name gets 
rebound to something different. This is because, in Python, the name binding 
operation ('=') *is* the declaration of the variable.

Rebinding a name often begs the question, "why are you using the same name for 
two different things in the one function?" It's not like using a different name 
for the second thing will cost much in terms of program size (unless you have 
some freakishly long functions) and it surely does little for readability. 
(Granted, iteration can be an exception, but even then the name generally only 
gets bound twice at most - once before the loop, and once in the loop body)

Consider all of the following cases which are detected while still preserving 
the convenience of 'name binding is declaration':
Py> def f():
...   x = y
...
Py> f()
Traceback (most recent call last):
   File "<stdin>", line 1, in ?
   File "<stdin>", line 2, in f
NameError: global name 'y' is not defined
Py> def f():
...   x += 1
...
Py> f()
Traceback (most recent call last):
   File "<stdin>", line 1, in ?
   File "<stdin>", line 2, in f
UnboundLocalError: local variable 'x' referenced before assignment
Py> def f():
...   oops = 1
...   print ooops
...
Py> f()
Traceback (most recent call last):
   File "<stdin>", line 1, in ?
   File "<stdin>", line 3, in f
NameError: global name 'ooops' is not defined
Py> def f():
...   class C: pass
...   c = C()
...   print c.x
...
Py> f()
Traceback (most recent call last):
   File "<stdin>", line 1, in ?
   File "<stdin>", line 4, in f
AttributeError: C instance has no attribute 'x'

Now, if someone were to suggest a *rebinding* operator, that worked just like 
regular name binding, but expected the name to be already bound, that would be 
an entirely different kettle of fish - you keep all the benefits of the current 
system, but gain the typo-checking that the rest of the augmented assignment 
operators benefit from.

Hell, '@' just acquired rebinding semantics through its use in function 
decorator syntax, so how does it look?:

   S=0
   for eps in xrange(10):
     S @= S + ups

Meh. At symbols are still ugly. A full stop might work better, since the 
semantics aren't very different from a reader's point of view:

   S=0
   for eps in xrange(10):
     S .= S + ups

Anyway, the exact syntax isn't as important as the concept :)

Cheers,
Nick.

-- 
Nick Coghlan   |   ncoghlan at email.com   |   Brisbane, Australia
---------------------------------------------------------------
             http://boredomandlaziness.skystorm.net



More information about the Python-list mailing list