Поскольку вы знаете аргументы во время компиляции / расширения макроса, вам не нужно применять:
CL-USER 35 > (defmacro make-canned-format-macro (template field-names)
`(function (lambda ,field-names
(format nil ,template ,@field-names))))
MAKE-CANNED-FORMAT-MACRO
CL-USER 36 > (macroexpand-1 '(make-canned-format-macro "~A-powered ~A" (fuel device)))
(FUNCTION (LAMBDA (FUEL DEVICE) (FORMAT NIL "~A-powered ~A" FUEL DEVICE)))
T
Также нет необходимости заключать в кавычки в списке:
'('(a))
Такой код очень необычен.
Генерация кода во время выполнения
Имя -macro
не имеет смысла, поскольку оно выполняет функцию.Функция должна генерировать исполняемый код: либо используйте EVAL
, либо используйте COMPILE
.
CL-USER 56 > (defun make-canned-format-function (template field-names)
(compile nil `(lambda ,field-names
(format nil ,template ,@field-names))))
MAKE-CANNED-FORMAT-FUNCTION
CL-USER 57 > (loop
for (func-name format-string params)
in '((zoom-zoom "~A-powered ~A" (fuel device))
(delicious "~A ice cream" (flavor))
(thematic "~A: A ~A and ~A film" (title star co-star)))
do (setf (gethash func-name *cookie-cutter-functions*)
(make-canned-format-function format-string params)))
NIL
Построение с помощью макросов
CL-USER 77 > (defun make-canned-format-function-code (template fields)
`(lambda ,fields
(format nil ,template ,@fields)))
MAKE-CANNED-FORMAT-FUNCTION-CODE
CL-USER 78 > (defmacro def-canned-format-functions (ht description)
`(progn ,@(loop
for (func-name format-string params) in description
collect `(setf (gethash ',func-name ,ht)
,(make-canned-format-function-code format-string params)))))
DEF-CANNED-FORMAT-FUNCTIONS
CL-USER 79 > (pprint
(macroexpand-1
'(def-canned-format-functions
*foo*
((zoom-zoom "~A-powered ~A" (fuel device))
(delicious "~A ice cream" (flavor))
(thematic "~A: A ~A and ~A film" (title star co-star))))))
(PROGN
(SETF (GETHASH 'ZOOM-ZOOM *FOO*)
(LAMBDA (FUEL DEVICE)
(FORMAT NIL "~A-powered ~A" FUEL DEVICE)))
(SETF (GETHASH 'DELICIOUS *FOO*)
(LAMBDA (FLAVOR)
(FORMAT NIL "~A ice cream" FLAVOR)))
(SETF (GETHASH 'THEMATIC *FOO*)
(LAMBDA (TITLE STAR CO-STAR)
(FORMAT NIL "~A: A ~A and ~A film" TITLE STAR CO-STAR))))
В вашем коде вынаписал бы на верхнем уровне:
(def-canned-format-functions
*foo*
((zoom-zoom "~A-powered ~A" (fuel device))
(delicious "~A ice cream" (flavor))
(thematic "~A: A ~A and ~A film" (title star co-star))))