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

Thomas Bellman bellman at lysator.liu.se
Tue May 15 13:13:31 EDT 2001


cobrien at Radix.Net (Cary O'Brien) writes:

>> ...of the controlled code.  That is much easier in LISP than in any
>> other language I have seen.

> I think it is pretty easy to write new control structures in TCL,
> since you can eval a string in the calling context.  Like a 12 line
> tcl proc that loops over a SQL result set, binds the columns to
> variables, and runs the "body" of the loop.  Is this the same thing?

You missed one thing: the ability to do things to the code block
before evaluating it.  I'm not very good at TCL, but wouldn't you
need to get a TCL parser to figure out how the code block is
composed before you can change it?  The code block you get is
just a string, and you don't know the limits of the statements in
it without parsing it.  In LISP you get that parsing automatically.

Assume that you have a bunch of things to do.  Before each
operation, you want to call spam(), and after the operation, you
want to call eggs().  I.e the equivalent of

    def spam_and_eggs(code):
	spam()
	exec code
	eggs()

In LISP:

    (defmacro spam-and-eggs (&rest code)
      `(progn
	 (spam)
	 , at code
	 (eggs)))

Now, you have fifty different things that you want to do, each
thing "protected" with spam-and-eggs, and they should be done in
a row:

    (spam-and-eggs
      (do-first-thing ...))
    (spam-and-eggs
      (do-second-thing ...))
    (spam-and-eggs
      (dotimes (i 17)
	(do-third-thing i)))
    ...
    (spam-and-eggs
      (if (test-something)
	(do-fifty-th-thing)))

You soon get tired of typing "spam-and-eggs"...  So instead you
define this macro:

    (defmacro multi-spam-and-eggs (&rest code)
      (mapcar (lambda (expr) `(progn (spam) ,expr (eggs)))
	      code))

and now you can do

    (multi-spam-and-eggs
      (do-first-thing ...)
      (do-second-thing ...)
      (dotimes (i 17)
	(do-third-thing i))
      ...
      (if (test-something)
	(do-fifty-th-thing)))

(And for those of you who don't understand all this, the Python
equivalent would be to define a control structure that allowed
you to write

    multi_spam_and_eggs:
	do_first_thing()
	do_second_thing()
	for i in range(17):
	    do_third_thing(i)
	...
	if test_something():
	    do_fifty_th_thing()

which would expand to

    spam()
    do_first_thing()
    eggs()
    spam()
    do_second_thing()
    eggs()
    spam()
    for i in range(17):
	do_third_thing(i)
    eggs()
    spam()
    ...
    eggs()
    spam()
    if test_something():
	do_fifty_th_thing()
    eggs()
)

In LISP, the macro basically gets passed a parse tree of the
code.  (Or of whatever kind of data you give it as an argument;
LISP doesn't distinguish between code and data the way many other
languages do.)


-- 
Thomas Bellman,   Lysator Computer Club,   Linköping University,  Sweden
"We don't understand the software, and        ! bellman @ lysator.liu.se
 sometimes  we don't understand the hardware, ! 
 but we can *see* the blinking lights!"       ! Make Love -- Nicht Wahr!



More information about the Python-list mailing list