merits of Lisp vs Python

Steven D'Aprano steve at REMOVE.THIS.cybersource.com.au
Sun Dec 10 09:59:15 EST 2006


On Sun, 10 Dec 2006 00:03:11 -0800, Wolfram Fenske wrote:

[snip]
> Doesn't matter because it only has to be written once.  For Common
> Lisp it's already part of the language.  It would of course be bad to
> write a macro if pattern comes up only a few times.  But that's not how
> macros are used.

So you say. I've heard it be said that anytime you do anything more than
once, you should abstract it away into a function or macro. 

Of course, that was the same person who told me that no function should
ever be more than five lines of code, so perhaps you might consider him
prone to over-stating his case.



[snip]
>> Saving one line of code, at the expense of having another block of code
>> to write or understand -- is that really the best example of what
>> macros are used for in practice? You don't really save writing any
>> boilerplate code, except for else clause, unless you're claiming that
>> "if" and "elif" is boilerplate.
> 
> No, all the "if control_code == SOME_STATUS:" are boilerplate:

You still have to include SOME_STATUS in the Lisp example. Calling it
boilerplate for Python is unfair. 

[snip]
> The pattern is that one value is compared against several possible
> values and depending on which one matches, the appropriate action is
> taken.  Common Lisp's CASE and ECASE macros and the "switch" statements
> of C or Java make this pattern explicit and arguably easier to
> recognize.  In Python you have to type it out yourself.

Yes, Python doesn't have a case/switch statement. It may get one in the
future. There are advantages to a case statement, but they aren't
overwhelming, and there are costs to implementing it. 


>> Okay, I'm impressed that ecase can pick up on the four constants being
>> tested against, and feed their names (rather than merely their values)
>> into an error message. Python has nothing like that, and if you only
>> have three or four things to test against, *and* they have names, that
>> could be a useful thing to do. And if I've understood correctly, that's
>> more a feature of Lisp's symbols than of macros.
>>
>> But if you're testing against fifty different values, well, is it
>> really useful for your error message to list all fifty names? Or do you
>> have another macro ecase-with-lots-of-tests?
> 
> Now you're being silly.

How am I being silly? Do you not believe that people write case blocks
with fifty tests? Okay, how about twenty? Ten? Eight?

One of the advantages of Lisp's ecase macro was specifically stated to be
that it gave you the error message for free, without the coder having to
add new terms to the message as they add new comparisons. Why is it
"silly" to question whether that feature is always useful?


[snip]

> Here's another example.  I had to use a database in one of my Python
> programs.  Everytime I used the database I had write something like
> this:
[snip]
> In Lisp, I could just write a macro "WITH-CONNECTION" that takes the
> name of the connection variable and the code for "do something with the
> connection" as arguments.  Actually, I ended up writing something like
> it as a function in Python:
> 
>  --8<---------------cut here---------------start------------->8---
>         def withConnection(self, fun):
>             self.lock.acquire()
>             try:
>                 connection = sqlite.connect(self.dbFile)
>                 connection.row_factory = dictFactory
>                 try:
>                     return fun(connection)
>                 finally:
>                     connection.close()
>             finally:
>                 self.lock.release()
> --8<---------------cut here---------------end--------------->8---
> 
> What would have been the body in the Lisp macro has to be supplied as
> function.  It's basically a macro, but it still requires more typing
> because you have to define a local function eveytime it is used.

Hang on -- why can't you just call the function again?

If you're talking about calling withConnection with different functions,
then of course you have to define a different function each time. How is
that different from the Lisp macro? You still have to write that.

And these functions -- shouldn't they be tested? If they were just
anonymous blocks, won't they be hard to test? These aren't rhetorical
questions.



-- 
Steven.




More information about the Python-list mailing list