Макросы раскрываются во время компиляции, поэтому ваша переменная possible-states
должна быть константой времени компиляции.Если это не так (или если вы не совсем понимаете, о чем я говорю выше), вам следует не использовать здесь макрос.
Использовать функциювместо этого:
(funcall (cdr (find current-state possible-states :key #'car :test #'eq)))
или
(funcall (cdr (assoc current-state possible-states :test #'eq)))
или, что еще лучше, создайте possible-states
хэш-таблицу , а не список ассоциаций :
(funcall (gethash current-state possible-states))
Однако, если ваша possible-states
является постоянной времени компиляции, вы можете использовать макрос, за исключением того, что вы, вероятно, хотитеиспользовать case
вместо 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
Обратите внимание, что с точки зрения speed , gethash
версия, вероятно, идентична версии макроса (по крайней мере, она не медленнее).