Python vs. Lisp -- please explain

Rocco Moretti roccomoretti at hotpop.com
Wed Feb 22 13:45:16 EST 2006


Alexander Schmolck wrote:
> I wanted to point
> out that one could with just as much justification claim CL to be more dynamic
> than python (it is in some regards, but not in others -- how to weight them to
> achieve some overall "score" is not obvious. 

I think it's worth pointing out that not all dynamicism is equal, when 
it comes to difficulty in compiling to machine code.

> For example in CL you could just write
> 
>   def foo(x, l=[], N=len(l)): [...]

Although computing default arguments at call-time vs. define-time is 
arguably more dynamic, it really doesn't (appreciably) increase the 
difficulty in creating machine code.

I think (see Caveat) that the one major difference between Lisp and 
Python that has a major bearing on compilability is mutability.

Lisp, like the good functional language that it is, has (primarily) 
immutable values, and minimal side effects. That is, you can make a 
function that takes in one value, and outputs a different value, but 
once you have a handle on a value, that value doesn't ever change. That 
makes it comparatively easy to track value paths, and assign proper 
machine code to each operation.

Python, on the other hand, is mutable to an absurd degree, with 
reassignments and side effects galore. Even a relatively simple function 
like:

def f():
     act(module.value)
     random_function()
     act(module.value)

can't be (automatically) replaced with the "obvious" equivalent:

def f():
     mv = module.value
     act(mv)
     random_function()
     act(mv)

because of the off chance that random_function() will reassign 
module.value. Even if you look at random_function(), and rule out a 
change to module.value, there is always a chance that a some other 
thread will alter module.value in the mean time. Trivial example, true, 
but when you figure that you can do the same to any operation or builtin 
function, the compiler is never quite sure what a particular function 
will do, what side effects it may have, or what type it will return. In 
order to be ready for any contingency, a compiled Python program will 
effectively have to incorporate the entire interpreter.

C/C++ gets around the mutability issue by straight-jacketing types & 
functions. A variable will only contain a particular type (or a 
subclass), and a function always has a particular signature.

Granted, there are ways of doing heavy duty code analysis, and pinning 
down functions, types, and side effects in Python, and 
Psyco/PyPy/ShedSkin are making good strides in that regards. But due to 
the heavy dependency on mutable objects and side effects in Python, such 
analysis will never be as easy as with Lisp, and considering Python has 
had less time, and less investment in those areas, it's no wonder that 
it's only just now seeing progress on the compiler front.


* Caveat: I've never seriously programmed in Lisp, and the last time I 
looked at it was some time ago, with not-up-to-date reference materials. 
I might be mistaken about the extent of mutability in current versions 
of Lisp. Hopefully others with more knowledge can give more accurate 
details of mutability/side effects in Lisp vis-a-vis ease of compilation.




More information about the Python-list mailing list