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

Alex Martelli aleaxit at yahoo.com
Tue May 15 03:56:17 EDT 2001


"Steven D. Majewski" <sdm7g at Virginia.EDU> wrote in message
news:mailman.989895922.17958.python-list at python.org...
    ...
>  There are forms that evaluate all of their arguments and
>  there are forms that don't evaluate all of their arguments.
>
>  The first bunch are called function and you can define your own.
>
>  The second bunch are called "special forms" and include things
>  like IF, WHILE, SETQ and WITH-OPEN-FILE, and you can also define
>  your own using what are called Macros.

Excellent summary!


>  ( Smalltalk, instead of having these different forms, has a way
>    of slinging around unevaluated code blocks as parameters:

And Haskell has an even more elegant architecture, in my own
humble opinion: *NOTHING* is ever evaluated until and unless
its specific value is needed (OK, OK, so I'm over-simplifying,
but it ain't all that far...).  This "normal order evaluation"
more colloquially and expressively "lazy evaluation", has an
extreme elegance, and does away with the need to distinguish
functions from special-forms, code-blocks from other values,
finite sequences from infinite ones, and so on.  Alas, it's
true that it only really works 'just right' when there are no
side effects (functional programming...) AND even then it may
impose substantial performance costs (but that takes us back
to performance-optimization issues:-).


In Python, an unevaluated code block, in the general case, is
expressed as a function-body -- the "literal form" (lambda)
is so limited as to be almost unusable, so you gotta name it.

The equivalent of your Smalltalk example:

    object ifTrue: [ block of code to be evaluated ]
   ifFalse: [ block of code to be evaluated ]

would therefore need rather-different syntax sugar, e.g:

    def ifTrue():
        # one block of code to be evaluated
    def ifFalse():
        # another block to be evaluated
    object(ifTrue=ifTrue, ifFalse=ifFalse)

assuming the object's __call__() method is the one that
performs the true/false selection.  The syntax-sugar
difference is large indeed, when compared to either the
Smalltalk syntax OR Python's own builtin "special forms"
such as if/else.  The fact of having to name your code
blocks before you pass them as unevaluated-arguments
takes no semantic power away, but in practice this is
not a very frequent Python idiom -- most Pythonistas
just don't often code that way, and some of those who
DO (such as, yours truly:-) affect a deep indifference
for "mere syntax-sugar issues", so there's no pressure
from either "constituency" to remove the "inconvenience"
(at a syntax-sugar level) of having to name the blocks.
[Personally, I *LIKE* giving my codeblocks names, though
I choose more significant ones than 'ifTrue'/'ifFalse':-)].

The "constituency for change" in this regard would thus
appear to be limited to people who BOTH appreciate this
"passing unevaluated codeblocks" programming style AND
at the same time care a lot about the exact syntax-sugar
to be used for the purpose.  Surely a non-null set, mind
you.  There may be a further split of it between those
who believe the obvious way forward would be to just
supply some nice sugar for unnamed & unevaluated code
blocks, and those who'd place even more emphasis on the
sugary aspects by focusing on the 'macro' possibilities.


Alex






More information about the Python-list mailing list