1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
;I create this function:
(defun list-pairs (pair-list)
  (cond ((not pair-list)
         nil)
        (t
         (destructuring-bind (a b &rest rest) pair-list
           (cons (list (intern (symbol-name a)) b) (list-pairs rest)))))

;This is okay:
CL-USER> (list-pairs '(:fee "hi" :fie "ho"))
((FEE "hi") (FIE "ho"))

;So is this:
CL-USER> (setf vals '(:fee "hi" :fie "ho"))
(:FEE "hi" :FIE "ho")
CL-USER> (list-pairs vals)
((FEE "hi") (FIE "ho"))

;Then I create this function:
(defmacro let-list* (key-vals &body body)
  `(let* ,(list-pairs key-vals)
     ,@body))

;This works:
CL-USER> (macroexpand-1 '(let-list* (:fee "hi" :fie "ho") (format t "~s ~s its off to work I go." fee fie)))
(LET* ((FEE "hi") (FIE "ho"))
  (FORMAT T "~s ~s its off to work I go." FEE FIE))
T
CL-USER> (let-list* (:fee "hi" :fie "ho") (format t "~s ~s its off to work I go." fee fie))
"hi" "ho" its off to work I go.
NIL

;But this doesn't:
CL-USER> (macroexpand-1 '(let-list* vals (format t "~s ~s its off to work I go." fee fie)))
Error while parsing arguments to DESTRUCTURING-BIND:
  invalid number of elements in
    VALS
  to satisfy lambda list
    (A B &REST REST):
  at least 2 expected, but got a non-list
   [Condition of type SB-KERNEL::ARG-COUNT-ERROR]

;Why, and what do I need to do to get the value "passed in" or whatever terminology is used to describe the parameters in a call to a macro, to be expanded to their value to be provided to the function list-vals?