Skip to content

Commit 994a413

Browse files
committed
fix problem from errata to make acond and acond2 act more like cond
1 parent a74e309 commit 994a413

1 file changed

Lines changed: 36 additions & 10 deletions

File tree

src/chapter-14.lisp

Lines changed: 36 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,19 @@
2222
((null (cdr args)) (car args))
2323
(t `(aif ,(car args) (aand ,@(cdr args))))))
2424

25+
;; version in book
26+
#+nil
27+
(defmacro acond (&rest clauses)
28+
(if (null clauses)
29+
nil
30+
(let ((cl1 (car clauses))
31+
(sym (gensym)))
32+
`(let ((,sym ,(car cl1)))
33+
(if ,sym
34+
(let ((it ,sym)) ,@(cdr cl1))
35+
(acond ,@(cdr clauses)))))))
2536

26-
;; problem noted by pg but no fix given
27-
;; http://www.paulgraham.com/onlisperrata.html:
37+
;; Corrected problem in http://www.paulgraham.com/onlisperrata.html:
2838
;; p. 191 (acond (3)) returns nil when it should return 3.
2939
;; Same problem with acond2, p. 198. Caught by Terrence Ireland.
3040
(defmacro acond (&rest clauses)
@@ -34,9 +44,11 @@
3444
(sym (gensym)))
3545
`(let ((,sym ,(car cl1)))
3646
(if ,sym
37-
(let ((it ,sym))
38-
(declare (ignorable it)) ;; not in original code
39-
,@(cdr cl1))
47+
,(if (null (cdr cl1))
48+
sym ;; return result of test if no non-test forms in clause
49+
`(let ((it ,sym))
50+
(declare (ignorable it)) ;; not in original code
51+
,@(cdr cl1)))
4052
(acond ,@(cdr clauses)))))))
4153

4254
;; p. 193
@@ -85,8 +97,20 @@
8597
(progn ,@body)
8698
(setq ,flag nil))))))
8799

88-
;; problem noted by pg but no fix given
89-
;; http://www.paulgraham.com/onlisperrata.html:
100+
;; version in book
101+
#+nil
102+
(defmacro acond2 (&rest clauses)
103+
(if (null clauses)
104+
nil
105+
(let ((cl1 (car clauses))
106+
(val (gensym))
107+
(win (gensym)))
108+
`(multiple-value-bind (,val ,win) ,(car cl1)
109+
(if (or ,val ,win)
110+
(let ((it ,val)) ,@(cdr cl1))
111+
(acond2 ,@(cdr clauses)))))))
112+
113+
;; Corrected problem in http://www.paulgraham.com/onlisperrata.html:
90114
;; p. 191 (acond (3)) returns nil when it should return 3.
91115
;; Same problem with acond2, p. 198. Caught by Terrence Ireland.
92116
(defmacro acond2 (&rest clauses)
@@ -97,9 +121,11 @@
97121
(win (gensym)))
98122
`(multiple-value-bind (,val ,win) ,(car cl1)
99123
(if (or ,val ,win)
100-
(let ((it ,val))
101-
(declare (ignorable it)) ;; not in original code
102-
,@(cdr cl1))
124+
,(if (null (cdr cl1))
125+
val ;; return result of test if no non-test forms in clause
126+
`(let ((it ,val))
127+
(declare (ignorable it)) ;; not in original code
128+
,@(cdr cl1)))
103129
(acond2 ,@(cdr clauses)))))))
104130

105131
;; p. 199

0 commit comments

Comments
 (0)