What can you do in LISP that you can't do in Python

Thomas Bellman bellman at lysator.liu.se
Tue May 15 01:47:54 CEST 2001


"Richard P. Muller" <rpm at wag.caltech.edu> writes:

> However, thus far I can't see anything that I could do in Scheme that I
> couldn't do in Python. From the thread on LISP I've seen a lot of
> comments that have suggested that I should have started with Common Lisp
> instead of Scheme -- so maybe that's the problem. But can someone give
> me a short example of something that I can do in LISP that I couldn't do
> in Python?

As others have already said: manipulating code.  Macros.

In LISP it is easy to define new control structures with slightly
different, or entirely new, semantics from those that are already
present in the language.  A couple of examples:

Assume that you want to define a function.  It should first call
spam(), then eggs(), then do a bunch of things, and finally call
parrot(), before returning the value computed by the expression
just before the parrot() call.  In Python, this would be:

    def myfunc(...):
	spam()
	eggs()
	...statements...
	result = ...expression...
	parrot()
	return result

Not too difficult, right?  Now assume that don't want to define
one such function, but one *hundred*.  Wouldn't it then be nice
to have a special mydef construct, so you could say

    mydef myfunc1(...):
	...statements...
	...expression...
    mydef myfunc2(...):
	...statements...
	...expression...
    ...

This is quite easy to do with LISP macros.  You can do similiar
things in Python by using classes and a mixin class, like:

    class mymixin:
	def __call__(self, ...):
	    spam()
	    eggs()
	    result = self.special_method(...)
	    parrot()
	    return result

    class myclass1(mymixin):
	def special_method(dummy, ...):
	    ...statements...
	    return ...expression...
    myfunc1 = myclass1()
    class myclass2(mymixin):
	def special_method(dummy, ...):
	    ...statements...
	    return ...expression...
    myfunc2 = myclass2()
    ...

but it gets a bit clunky.


Another example:

You have a (global) data structure.  You want to manipulate it,
then test if something works, and if it doesn't, you need to
restore the data structure to its original value.  Easy:

    saved = data_structure.copy()
    try:
	...do manipulations...
	...test for something...
    except didnt_work:
	data_structure = saved

If you need to do this in many places, with different kinds of
manipulations and/or tests, it might be easier to define a
special version of try, that does the saving and restoring of the
old value automatically.  Especially when the saving and restoring
isn't just a single line each.  Then you could do:

    restoring_try:
	...do manipulations...
	...test for something...
    ...
    restoring_try:
	...do other manipulations...
	...test for something else...

Sure, you could do this as a function taking another function as
an argument:

    def restoring_try(func, *args):
	global data_structure
	saved = data_structure.copy()
	try:
	    func(*args)
	except didnt_work:
	    data_structure = saved

but then you need to define a new function for each instance of
manipulation/test you have in your program, and that gets old
real fast.


Then the fact that the parse tree of LISP code is *obvious* from
its textual representation, combined with backquote/comma
expressions, makes several kinds of code manipulation very, easy.

In the examples above, the new control structures only do extra
things before and after the code block they control, but one
could think of examples where things should be done in the middle
of the controlled code.  That is much easier in LISP than in any
other language I have seen.

Sure, in many cases you could redesign your program to avoid the
need for those constructs, but sometimes that other design
becomes forced and unnatural.


Hope this at least gives you a few ideas of what can be done in
LISP.


-- 
Thomas Bellman,   Lysator Computer Club,   Linköping University,  Sweden
"You cannot achieve the impossible without   !  bellman @ lysator.liu.se
 attempting the absurd."                     !  Make Love -- Nicht Wahr!



More information about the Python-list mailing list