;;; Figure 10.1: Controlling argument evaluation.
;; 올바른 버전
(defmacro for-correct ((var start stop) &body body)
(let ((gstop (gensym)))
`(do ((,var ,start (1+ ,var))
(,gstop ,stop))
((> ,var ,gstop))
,@body)))
;; 여러 번 평가:
(defmacro for-eval ((var start stop) &body body)
`(do ((,var ,start (1+ ,var))) ; 올바른 버전에 비해, gensym을 사용하지 않았다.
((> ,var ,stop))
,@body))
;; 옳지 않은 평가 순서:
(defmacro for-order ((var start stop) &body body)
(let ((gstop (gensym)))
`(do ((,gstop ,stop)
(,var ,start (1+ ,var))) ; 올바른 버전에 비해, 1+ 가 아래에 있다
((> ,var ,gstop))
,@body)))
(setq x 10)
(+ (setq x 3) x)
;;=> 6
(let ((x 1))
(for-order (i x (setq x 13))
(princ i)))
;;>> 13
;;=> NIL
(let ((x 1))
(for-correct (i x (setq x 13))
(princ i)))
;;>> 12345678910111213
;;=> NIL