[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
dolist
>>>>> "Paul" == pg <pg@das.harvard.edu> writes:
Paul> The question is, should dolist be understood
Paul> as creating one variable (as it would if it expanded into a
Paul> tagbody with a setq) or a different variable on each iteration
Paul> (as it would if it expanded into a recursive function). I
Paul> believe that the standard is vague here, and was suggesting that
Paul> if we have to choose one interpretation, the latter would be the
Paul> better one, as in Scheme.
There isn't really a performance penalty to having an extra LET.
CMU Lisp adds the extra LET and GCL does not (like CLISP currently
does). On the other hand, perhaps it is useful to have the option
of rebinding it if you want to, as Ken Olum points out.
To me, the CL spec does seem to lean toward an extra binding
by saying "bound" instead of "assigned".
Opinions and/or slaps-in-the-head ?
Here is what the change would look like:
Index: macros1.lsp
===================================================================
RCS file: /u/marcus/cvs/clisp/src/macros1.lsp,v
retrieving revision 1.1.1.1
diff -c -r1.1.1.1 macros1.lsp
*** macros1.lsp 1995/09/10 10:54:34 1.1.1.1
--- macros1.lsp 1996/04/28 23:47:04
***************
*** 232,239 ****
(multiple-value-bind (body-rest declarations)
(sys::parse-body body nil env)
(let ((g (gensym)))
! `(DO* ((,g ,listform (CDR ,g))
! (,var NIL))
((ENDP ,g)
,(if (constantp resultform)
; Ist resultform konstant, so ist es /= var. Daher braucht var
--- 232,238 ----
(multiple-value-bind (body-rest declarations)
(sys::parse-body body nil env)
(let ((g (gensym)))
! `(DO* ((,g ,listform (CDR ,g)))
((ENDP ,g)
,(if (constantp resultform)
; Ist resultform konstant, so ist es /= var. Daher braucht var
***************
*** 246,253 ****
)
)
(DECLARE (LIST ,g) ,@declarations)
! (SETQ ,var (CAR ,g))
! ,@body-rest
)
) ) )
--- 245,253 ----
)
)
(DECLARE (LIST ,g) ,@declarations)
! (LET ((,var (CAR ,g)))
! ,@body-rest
! )
)
) ) )
In isolation:
(defmacro dolist ((var listform &optional resultform) &body body &environment env)
(multiple-value-bind (body-rest declarations)
(sys::parse-body body nil env)
(let ((g (gensym)))
`(DO* ((,g ,listform (CDR ,g)))
((ENDP ,g)
,(if (constantp resultform)
; Ist resultform konstant, so ist es /= var. Daher braucht var
; während Auswertung von resultform nicht an NIL gebunden zu sein:
`,resultform
`(LET ((,var NIL))
(DECLARE (IGNORABLE ,var) ,@declarations)
,resultform
)
)
)
(DECLARE (LIST ,g) ,@declarations)
(LET ((,var (CAR ,g)))
,@body-rest
)
)
) ) )