Macros are expanded at compile time, so your possible-states variable has to be a compile-time constant. If this is not the case (or if you are not absolutely clear on what I mean above), you should not use a macro here.
Use a function instead:
(funcall (cdr (find current-state possible-states :key #'car :test #'eq)))
or
(funcall (cdr (assoc current-state possible-states :test #'eq)))
or, better yet, make your possible-states a hash
table rather than an association
list:
(funcall (gethash current-state possible-states))
However, if your possible-states is a compile time constant, you
can, indeed, use a macro, except that you probably want to use
case instead of
cond:
(defmacro state-dispatch (state)
`(case ,state
,@(mapcar (lambda (cell)
`((,(car cell)) (,(cdr cell))))
possible-states)))
(defparameter possible-states '((1 . foo) (2 . bar)))
(macroexpand-1 '(state-dispatch mystate))
==> (CASE MYSTATE ((1) (FOO)) ((2) (BAR))) ; T
Note that from the speed point of view, the gethash version is probably identical to the macro version (at the very least it is not slower).
mapcaris there for? to splice a list in place,,@can be used. - Will Ness