Python syntax in Lisp and Scheme

Marco Antoniotti marcoxa at cs.nyu.edu
Tue Oct 7 09:14:41 EDT 2003


David Eppstein wrote:

> In article 
> <my-first-name.my-last-name-0610030955090001 at k-137-79-50-101.jpl.nasa.go
> v>,
>  my-first-name.my-last-name at jpl.nasa.gov (Erann Gat) wrote:
> 
> 
>>>: Here's another example of what you can do with macros in Lisp:
>>>
>>>: (with-collector collect
>>>:   (do-file-lines (l some-file-name)
>>>:     (if (some-property l) (collect l))))
>>>
>>>: This returns a list of all the lines in a file that have some property. 
>>>
>>>OK, that's _definitely_ just a filter: filter someproperty somefilename
>>>Perhaps throw in a fold if you are trying to abstract "collect".
>>
>>The net effect is a filter, but again, you need to stop thinking about the
>>"what" and start thinking about the "how", otherwise, as I said, there's
>>no reason to use anything other than machine language.
> 
> 
> Answer 1: literal translation into Python.  The closest analogue of 
> with-collector etc would be Python's simple generators (yield keyword) 
> and do-with-file-lines is expressed in python with a for loop.  So:
> 
> def lines_with_some_property(some_file_name):
>     for l in some_file_name:
>         if some_property(l):
>             yield l
> 
> Your only use of macros in this example is to handle the with-collector 
> syntax, which is handled in a clean macro-free way by Python's "yield".
> So this is unconvincing as a demonstration of why macros are a necessary 
> part of a good programming language.
> 
> Of course, with-collector could be embedded in a larger piece of code, 
> while using yield forces lines_with_some_property to be a separate 
> function, but modularity is good...

BZZZZZT!  In CL the WITH-COLLECTOR macro is best defined as

	(defmacro with-collector (collector-name &body forms) ...)

That is to say that you can write things as

	(with-collector collect
	  (let ...
	     (block ...
	       (loop ...
	          (dotimes ... (collect whatever))))))

This means that your Python function is *NOT* equivalent to the CL 
macro.  Not even with your 'yield' (easily implementable in CL: meaning, 
in CL).

> 
> Answer 2: poetic translation into Python.  If I think about "how" I want 
> to express this sort of filtering, I end up with something much less 
> like the imperative-style code above and much more like:
> 
> [l for l in some_file_name if some_property(l)]

Very interesting.  The CL equivalent is

	[l in (lines-of some-file-name) if (some-property l)]

Now: I do have an implementation of this in CL. (I assume that your 
'some_file_name' is not just a string).

> 
> I have no problem with the assertion that macros are an important part 
> of Lisp, but you seem to be arguing more generally that the lack of 
> macros makes other languages like Python inferior because the literal 
> translations of certain macro-based code are impossible or more 
> cumbersome.  For the present example, even that argument fails, but more 
> generally you'll have to also convince me that even a freer poetic 
> translation doesn't work.

Well, the argument does not fail even in these cases as closer 
inspection reveals.  There are things you cannot do in Python that you 
can easily do in CL.  It is the converse that is only asymptotically 
provable as a rhethoric exercise :)

Greenspun's Tenth Rules! :)

Cheers
--
Marco








More information about the Python-list mailing list