Skip to content

Instantly share code, notes, and snippets.

@cametan001
Created May 15, 2010 21:16
CL-USER> (let ((var0 0))
(my-while%% (< var0 10)
(print var0)
(incf var0)))
; in: LAMBDA NIL
; (LET ((VAR0 0))
; (MY-WHILE%% (< VAR0 10) (PRINT VAR0) (INCF VAR0)))
;
; caught STYLE-WARNING:
; The variable VAR0 is defined but never used.
;
; compilation unit finished
; caught 1 STYLE-WARNING condition
; Evaluation aborted.
CL-USER> (let ((var1 0))
(my-while%% (< var1 10)
(print var1)
(incf var1)))
; in: LAMBDA NIL
; (LET ((VAR1 0))
; (MY-WHILE%% (< VAR1 10) (PRINT VAR1) (INCF VAR1)))
;
; caught STYLE-WARNING:
; The variable VAR1 is defined but never used.
;
; compilation unit finished
; caught 1 STYLE-WARNING condition
; Evaluation aborted.
CL-USER>
CL-USER> (let ((i 0))
(my-while (< i 10)
(print i)
(incf i)))
0
1
2
3
4
5
6
7
8
9
9 ; 返り値は9!!!
CL-USER> (let ((var0 0))
(my-while (< var0 10)
(print var0)
(incf var0)))
0
1
2
3
4
5
6
7
8
9
9 ; 多い日も安心!
CL-USER> (let ((var1 0))
(my-while (< var1 10)
(print var1)
(incf var1)))
0
1
2
3
4
5
6
7
8
9
9 ; 横モレしない!
CL-USER>
(defmacro! my-while! (test &body body)
`(do ((,g!var0 nil ,@(last body))
(,g!var1 nil ,g!var0))
((not ,test) ,g!var1)
,@(butlast body)))
(defmacro my-while (test &body body)
;; テンプレートの外部で var0、var1 で gensym を束縛する
(let ((var0 (gensym)) (var1 (gensym)))
`(do ((,var0 nil ,@(last body))
(,var1 nil ,var0))
((not ,test) ,var1)
,@(butlast body))))
(defmacro my-while2 (test &body body)
(let ((self (gensym)) (exp (gensym)) (acc (gensym)))
`(labels
((,self (,exp ,acc)
(if (not, test)
,acc
(,self (progn ,@body) ,exp))))
(,self (progn ,@body) nil))))
(defmacro! my-while2! (test &body body)
`(labels
((,g!self (,g!exp ,g!acc)
(if (not ,test)
,g!acc
(,g!self (progn ,@body) ,g!exp))))
(,g!self (progn ,@body) nil)))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment