[comp.lang.lisp] DOLIST as DO

alex@soi.UUCP (Alex Zatsman) (07/14/88)

Anybody knows an elegant way of representing DOLIST construct
through DO ?  How about DO* ?

jackson@esosun.UUCP (Jerry Jackson) (07/15/88)

In article <327@soi.UUCP> alex@soi.UUCP (Alex Zatsman) writes:

   Path: esosun!seismo!uunet!yale!husc6!soi!alex
   From: alex@soi.UUCP (Alex Zatsman)
   Newsgroups: comp.lang.lisp
   Keywords: dolist do do*
   Date: 14 Jul 88 15:09:55 GMT
   Organization: Software Options Inc.,  Cambridge,  Mass.
   Lines: 2

   Anybody knows an elegant way of representing DOLIST construct
   through DO ?  How about DO* ?



How about...


(defmacro dolist ((var list &optional result-form) &rest body)
  (let ((listvar (gensym)))
    `(do* ((,listvar ,list (cdr ,listvar))
	  (,var (car ,list) (car ,listvar)))
	 ((null ,listvar) ,result-form)
	 ,@body)))


or...


(defmacro dolist ((var list &optional result-form) &rest body)
  (let ((listvar (gensym)))
    `(do ((,listvar (cdr ,list) (cdr ,listvar))
	  (,var (car ,list) (car ,listvar)))
	 ()
	 ,@body
	 (when (null ,listvar)
	   (return ,result-form)))))



+-----------------------------------------------------------------------------+
|   Jerry Jackson                       UUCP:  seismo!esosun!jackson          |
|   Geophysics Division, MS/22          ARPA:  esosun!jackson@seismo.css.gov  |
|   SAIC                                SOUND: (619)458-4924                  |
|   10210 Campus Point Drive                                                  |
|   San Diego, CA  92121                                                      |
+-----------------------------------------------------------------------------+

ok@quintus.uucp (Richard A. O'Keefe) (07/16/88)

In article <228@esosun.UUCP> jackson@esosun.UUCP (Jerry Jackson) writes:
>In article <327@soi.UUCP> alex@soi.UUCP (Alex Zatsman) writes:
>   Anybody knows an elegant way of representing DOLIST construct
>   through DO ?  How about DO* ?
>How about...
>
>(defmacro dolist ((var list &optional result-form) &rest body)
>  (let ((listvar (gensym)))
>    `(do* ((,listvar ,list (cdr ,listvar))
>	  (,var (car ,list) (car ,listvar)))
>	 ((null ,listvar) ,result-form)
>	 ,@body)))

That's not going to work too well when the list happens to be empty,
is it?  A small change fixes that:

(defmacro dolist ((var list &optional result-form) &rest body)
    (let ((listvar (gensym)))
       `(do ((,listvar ,list (cdr ,listvar)))
	    ((null ,listvar) ,result-form)
	    (let ((,var (car ,listvar)))
		,@body))))

barmar@think.COM (Barry Margolin) (07/17/88)

In article <228@esosun.UUCP> jackson@esosun.UUCP (Jerry Jackson) writes:
>(defmacro dolist ((var list &optional result-form) &rest body)
>  (let ((listvar (gensym)))
>    `(do* ((,listvar ,list (cdr ,listvar))
>	    (,var (car ,list) (car ,listvar)))
>	   ((null ,listvar) ,result-form)
>	 ,@body)))

Both versions of your macro have a bug: they have ",list" in two
places in the expansion.  This will cause the list expression to be
evaluated twice, which could cause problems if it has side effects.
In the above case, both the second line of the DO* form should be

	(,var (car ,listvar) (car ,listvar))

Fixing the DO version is slightly more complicated.

Barry Margolin
Thinking Machines Corp.

barmar@think.com
{uunet,harvard}!think!barmar

kobryn@esosun.UUCP (Cris Kobryn) (07/18/88)

In article <169@quintus.UUCP> ok@quintus.uucp (Richard A. O'Keefe) writes:
>In article <228@esosun.UUCP> jackson@esosun.UUCP (Jerry Jackson) writes:
>>In article <327@soi.UUCP> alex@soi.UUCP (Alex Zatsman) writes:
>>   Anybody knows an elegant way of representing DOLIST construct
>>   through DO ?  How about DO* ?
>>How about...
>>
>>(defmacro dolist ((var list &optional result-form) &rest body)
>>  (let ((listvar (gensym)))
>>    `(do* ((,listvar ,list (cdr ,listvar))
>>	  (,var (car ,list) (car ,listvar)))
>>	 ((null ,listvar) ,result-form)
>>	 ,@body)))
>
>That's not going to work too well when the list happens to be empty,
>is it?  A small change fixes that:
>
>(defmacro dolist ((var list &optional result-form) &rest body)
>    (let ((listvar (gensym)))
>       `(do ((,listvar ,list (cdr ,listvar)))
>	    ((null ,listvar) ,result-form)
>	    (let ((,var (car ,listvar)))
>		,@body))))

Mr. Jackson's version works well in Allegro CL when the LIST arg is NIL.  
Consider the following  Allegro CL dribble-file, in which Mr. Jackson's 
DOLIST has been renamed DOLIST2 to distinguish it from the Allegro version:

	dribbling to file "/u3/kobryn/temp/dolist2.dribble"
 
	NIL 
	<cl> (dolist (i nil) (print i))

	NIL 
	<cl> (dolist2 (i nil) (print i))
	
	NIL 
	<cl> (dribble)

Perhaps you are unaware that according to CLtL (p. 262) (CAR NIL) => NIL?

-- Cris Kobryn

+----------------------------------------------------------------------------+
|   Cris Kobryn                         UUCP:  seismo!esosun!kobryn          |
|   Geophysics Division, MS/12          ARPA:  esosun!kobryn@seismo.css.gov  |
|   SAIC                                SOUND: (619)458-2697                 |
|   10210 Campus Point Drive                                                 |
|   San Diego, CA  92121                                                     |
+----------------------------------------------------------------------------+