Let's compare two different macros cl:loop and iterate. cl:loop (sbcl
version) doesn't try to copy its arguments. Iterate does.
(defun expand-and-print(what)
(let ((*print-circle* t)
(*print-level* nil))
(format t "~A" `(:orig ,what :expanded ,(sb-cltl2:macroexpand-all
what)))))
(expand-and-print '(loop for i from 0 to 10 do (print i)))
==>
(ORIG (LOOP FOR I FROM 0 TO 10 DO #1=(PRINT I)) <--here
EXPANDED
(BLOCK NIL
(LET ((I 0))
(DECLARE (TYPE (AND REAL NUMBER) I))
(TAGBODY
NEXT-LOOP
#1# <----here
(SETQ I (1+ I))
(IF (> I '10) (PROGN NIL (GO END-LOOP)) NIL)
(GO NEXT-LOOP)
END-LOOP))))
(expand-and-print '(iterate:iter (iterate:for i from 0 to 10) (print
i)))
==>
(ORIG (ITER (FOR I FROM 0 TO 10) (PRINT I)) <----1
EXPANDED
(LET* ((I NIL))
(BLOCK NIL
(TAGBODY
(SETQ I -1)
LOOP-TOP-NIL
(SETQ I (+ I 1))
(IF (> I 10) (GO LOOP-END-NIL))
(PRINT I) <---- different from 1 !
(GO LOOP-TOP-NIL)
LOOP-END-NIL)
NIL)))
So iterate copy (print i) , and (print i) from iterate macroexpansion
is not eq to (print i) from orginal code. It is not good. For example
debugger (sbcl) couldn't determine precise source code location for
(print i) ( via slime debugger v key)- just "somewhere inside iterate
macroexpansion", but for cl:loop it can...
Comments?
In article <························@i42g2000cwa.googlegroups.com>,
"Alexander" <········@gmail.com> wrote:
> Let's compare two different macros cl:loop and iterate. cl:loop (sbcl
> version) doesn't try to copy its arguments. Iterate does.
I suspect this is because ITERATE does a code walk of the body, looking
for subforms that it needs to replace because they use COLLECT. In the
process, it's creating a new, isomorphic body to put in the expansion.
It might be possible for it to optimize this to share code, but it would
be harder to implement for little benefit.
--
Barry Margolin, ······@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
*** PLEASE don't copy me on replies, I'll read them in the group ***