Python syntax in Lisp and Scheme
Erann Gat
my-first-name.my-last-name at jpl.nasa.gov
Fri Oct 3 19:46:01 EDT 2003
More information about the Python-list mailing list
Fri Oct 3 19:46:01 EDT 2003
- Previous message (by thread): Python syntax in Lisp and Scheme
- Next message (by thread): Python syntax in Lisp and Scheme
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
In article <92c59a2c.0310031345.57d20631 at posting.google.com>, jcb at iteris.com (MetalOne) wrote: > kalath at lycos.com (Mark Brady) wrote in message news:<e840346c.0310030302.6be0c378 at posting.google.com>... > > Personally I find Scheme and Common Lisp easier to read but that's > > just me, I prefer S-exps ... > > I am just barely familiar with Lisp and Scheme. However, I always > find comments like the above interesting. I have seen other people > make this claim also. > However, from an earlier post on comp.lang.python comparing a simple > loop. > > Scheme > (define vector-fill! > (lambda (v x) > (let ((n (vector-length v))) > (do ((i 0 (+ i 1))) > ((= i n)) > (vector-set! v i x))))) > > Python > def vector_fill(v, x): > for i in range(len(v)): > v[i] = x > > To me the Python code is easier to read, and I can't possibly fathom > how somebody could think the Scheme code is easier to read. It truly > boggles my mind. In Common Lisp you can write: (defun vector-fill (v x) (loop for i from 0 below (length v) do (setf (aref v i) x))) or (defun vector-fill (v x) (dotimes (i (length v)) (setf (aref v i) x))) But if you focus on examples like this you really miss the point. Imagine that you wanted to be able to write this in Python: def vector_fill(v, x): for i from 0 to len(v)-1: v[i] = x You can't do it because Python doesn't support "for i from ... to ...", only "for i in ...". What's more, you can't as a user change the language so that it does support "for i from ... to ...". (That's why the xrange hack was invented.) In Lisp you can. If Lisp didn't already have LOOP or DOTIMES as part of the standard you could add them yourself, and the way you do it is by writing a macro. That's what macros are mainly good for, adding features to the langauge in ways that are absolutely impossible in any other language. S-expression syntax is the feature that enables users to so this quickly and easily. > I can't see > why a LISP programmer would even want to write a macro. That's because you are approaching this with a fundamentally flawed assumption. Macros are mainly not used to make the syntax prettier (though they can be used for that). They are mainly used to add features to the language that cannot be added as functions. For example, imagine you want to be able to traverse a binary tree and do an operation on all of its leaves. In Lisp you can write a macro that lets you write: (doleaves (leaf tree) ...) You can't do that in Python (or any other langauge). 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. DO-FILE-LINES and WITH-COLLECTOR are macros, and they can't be implemented any other way because they take variable names and code as arguments. E. ---- P.S. Here is the code for WITH-COLLECTOR and DO-FILE-LINES: (defmacro with-collector (var &body body) (let ( (resultvar (gensym "RESULT")) ) `(let ( (,resultvar '()) ) (flet ( (,var (item) (push item ,resultvar)) ) , at body) (nreverse ,resultvar)))) (defmacro do-file-lines ((linevar filename &optional streamvar) &body body) (let ( (streamvar (or streamvar (gensym "S"))) ) `(with-open-file (,streamvar ,filename) (do ( (,linevar (read-line ,streamvar nil nil) (read-line ,streamvar nil nil)) ) ( (null ,linevar) ) , at body)))) Here's DOLEAVES: (defmacro doleaves ((var tree) &body body) `(walkleaves (lambda (,var) , at body) ,tree)) :-) (defun walkleaves (fn tree) (iterate loop1 ( (tree tree) ) (if (atom tree) (funcall fn tree) (progn (loop1 (car tree)) (and (cdr tree) (loop1 (cdr tree))))))) ; This is the really cool way to iterate (defmacro iterate (name args &rest body) `(labels ((,name ,(mapcar #'car args) , at body)) (,name ,@(mapcar #'cadr args)))) E.
- Previous message (by thread): Python syntax in Lisp and Scheme
- Next message (by thread): Python syntax in Lisp and Scheme
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
More information about the Python-list mailing list