During the first example (the database example) in Practical Common Lisp, the author uses a macro and a couple support functions in order to replace a larger function, named where. The code works fine when where is a function, but the macro setup returns "undefined variable" and "unbound variable" errors. (Note that I commented out the original function, restarted Emacs and recompiled my file once adding the where macro.)
The caught style-warning in the REPL is most suspect to me since the macro should evaluate with ROW rather than CD, according to the example. Why is ROW unused? How do I resolve this warning?
This is printed in the REPL:
; in: SELECT (WHERE :TITLE "Animals" :RIPPED T)
; (WHERE :TITLE "Animals" :RIPPED T)
; ==>
; #'(LAMBDA (ROW)
; (AND (EQUAL (GETF CD :TITLE) "Animals") (EQUAL (GETF CD :RIPPED) T)))
;
; caught STYLE-WARNING:
; The variable ROW is defined but never used.
; in: SELECT (WHERE :TITLE "Animals" :RIPPED T)
; (WHERE :TITLE "Animals" :RIPPED T)
; --> FUNCTION AND IF EQUAL
; ==>
; (GETF CD :TITLE)
;
; caught WARNING:
; undefined variable: CD
;
; compilation unit finished
; Undefined variable:
; CD
; caught 1 WARNING condition
; caught 1 STYLE-WARNING condition
This is printed in the debug space:
The variable CD is unbound.
[Condition of type UNBOUND-VARIABLE]
Here are the support functions and macro in my .lisp file:
; this function is used in both implementations. *db* is a (global) database
(defun select (selector-fn)
(remove-if-not selector-fn *db*))
(defun make-comparison-expr (field value)
`(equal (getf cd ,field) ,value))
(defun make-comparisons-list (fields)
(loop while fields
collecting (make-comparison-expr (pop fields) (pop fields))))
(defmacro where (&rest clauses)
`#'(lambda (row) (and ,@(make-comparisons-list clauses))))
I'm using SBCL, Emacs and Slime.