From: ·······@ziplip.com
Subject: Re: Explanation of macros; Haskell macros
Date: 
Message-ID: <CJIPEHCLCEEHIPEJD2N5PUGGPYD4KCOBMGOICHP3@ziplip.com>
Rolf Wester wrote:

> ·······@ziplip.com wrote:
>> Let's say you do not have the "for" keyword, but you have
>> "dolist" for iterating a list and "dotimes" - a simple
>> index loop. You want to create "for" just like in Python, and
>> you also want "for i in range(10000): print i" to be efficient
>> and avoid constructing the big list (maybe you do not have
>> enough memory). In Lisp, you can acomplish this with the
>> following macro:
>> 
>> (defmacro for(i in list &rest rest)
>>   (if (eql 'in in)
>>     (if (and (listp list)
>>              (eql (length list) 2)
>>              (eql 'range (first list))
>>              (integerp (second list)))
>>       `(dotimes (,i ,(second list)) ,@rest)
>>       `(dolist (,i ,list) ,@rest))
>>     (error "syntax error")))
>> 
>> 
> What will a Pythonista think about Lisp macros when he/she tries:
> 
> (defun f (n)
>    (for i in (range n)
>         (print i)))
> (f 10000)
> 
> Maybe the macro should better be written:
> 
> (defmacro for (i in list &rest rest)
>    (if (eql 'in in)
>      (if (and (listp list)
>               (eql (length list) 2)
>               (eql 'range (first list))
>               (or (integerp (second list)) (symbolp (second list))))
>        `(if (integerp ,(second list))
> (dotimes (,i ,(second list)) ,@rest)
> (error "not an integer"))
>        `(dolist (,i ,list) ,@rest))
>      (error "syntax error")))

You are correct in that my macro was flawed, but your
version is also incorrect. What will a Pythonista think
when he tries

(defun f(n)
  (for i in (range (+ 3 n))
       (print i)))

:-)

The right thing to do is to omit the check for integer-ness
or symbol-ness altogether:

(defmacro for(i in list &rest rest)
  (if (eql 'in in)
    (if (and (listp list)
             (eql (length list) 2)
             (eql 'range (first list)))
      `(dotimes (,i ,(second list)) ,@rest)
      `(dolist (,i ,list) ,@rest))
    (error "syntax error")))

Hey, Pythonistas! Don't jump to conclusions too soon. It's
easy to make errors in Lisp, but it's also easy to find them
(I found the error in Rolf's code right away :-P )
Macros and symbol objects still rule!!!

BTW, here is a version without commas, comma-ats or backquotes
(they are just syntax):

(defmacro for(i in list &rest rest)
  (if (eql 'in in)
    (if (and (listp list)
             (eql (length list) 2)
             (eql 'range (first list)))
      (list* 'dotimes (list i (second list)) rest)
      (list* 'dolist (list i list) rest))
    (error "syntax error")))
From: Marco Antoniotti
Subject: Re: Explanation of macros; Haskell macros
Date: 
Message-ID: <vxBgb.7$KR3.774@typhoon.nyu.edu>
·······@ziplip.com wrote:

> (defmacro for(i in list &rest rest)
>   (if (eql 'in in)
>     (if (and (listp list)
>              (eql (length list) 2)
>              (eql 'range (first list)))
>       (list* 'dotimes (list i (second list)) rest)
>       (list* 'dolist (list i list) rest))
>     (error "syntax error")))
        ^^^^^^^^^^^^^^^^^^^^

CL has PROGRAM-ERROR for this cases.

Cheers
--
Marco