Anyone ever overridden a builtin by accident?

Jacek Generowicz jacek.generowicz at cern.ch
Wed Sep 17 04:19:34 EDT 2003


ladasky at my-deja.com (John Ladasky) writes:

> In one of my programs I wrote...
> 
> c = max(a,b)

> Then, I finally spotted the problem.  At the beginning of my program I
> had defined a variable called "max"!  I had overridden the __builtin__
> function by mistake.


voblia at centras.lt (Ignas Mikalajunas) writes:

>     Common Lisp solves this problem in a pretty simple way - functions
> and variables are in separate namespaces

But it doesn't really _solve_ the problem, does it?  It solves the
problem of overriding function bindings with data bindings (and vice
versa), but does nothing to prevent overriding function bindings with
other function bindings.  Consider:

def list():
    print "list"

and the Common Lisp equivalent

(defun list ()
  (print "list"))

In both cases you're clobbering a built-in. The difference, however, is
that, in Python you've merely shadowed the built-in -- the original is
still there in Python's outermost scope (builtins), while in CL you
are attempting to replace the built-in[*]. 

Common Lisp "solves" it, by forbidding it. But I do not think that
implementations are required to enforce the rule, so some (eg clisp)
complain:

  [1]> (defun list () (print "list"))
  
  ** - Continuable Error
  DEFUN/DEFMACRO(LIST): #<PACKAGE COMMON-LISP> is locked
  If you continue (by typing 'continue'): Ignore the lock and proceed
  1. Break [2]> 

while others (eg CMUCL), let it pass silently:

  Loaded subsystems:
      Python 1.1, target Intel x86
      CLOS 18e (based on PCL September 16 92 PCL (f))
  * (defun list () (print "list"))
  
  LIST

(Python, BTW, is the name of CMUCL's compiler :-)

> all global variables are commonly named *booo* *bah* and etc. so if
> you are overriding a global variable you are at least aware of it ...

Although the real purpose of the asterisks is to warn you about the
fact that the variable is dynamically bound[+], and that any local
bindings that you may make for it, will also be dynamic. The asterisks
are another form of namespace separation, but they address an
orthogonal issue, and offer absolutely no protection against
clobbering global _function_ definitions; global function names have
no asterisks (because they are not dynamically bound[#]).


[*] To be fair, Lisp distinguishes global function definitions from
    local ones, while in Python they are always local, so one can
    argue that the CL equivalent of Python's def is really flet or
    labels, which leave the built-in functions well alone, just as is
    the case in Python.

[+] As opposed to lexically bound, which is the default in CL, and the
    only possibility in Python.

[#] Though it has been suggested recently, that dynamic function
    binding subsumes AOP ... but that's getting waaaaay off-topic.




More information about the Python-list mailing list