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