Common lisp 用宏生成动态函数
我正在组合一个宏来生成该样式的简单函数:Common lisp 用宏生成动态函数,common-lisp,Common Lisp,我正在组合一个宏来生成该样式的简单函数: (defun hello () (format t "hello~&")) 每个新功能都将被替换 (defmacro generate-echoers (list) `(let ((list-of-functions (loop for var in ,list collect `(defun ,(intern var) () (fo
(defun hello ()
(format t "hello~&"))
每个新功能都将被替换
(defmacro generate-echoers (list)
`(let ((list-of-functions
(loop for var in ,list
collect
`(defun ,(intern var) ()
(format t ,(concatenate var "~&"))))))
`(progn
,list-of-functions)))
我开发了上面的函数,它最终证明我还没有掌握报价时间和扩展阶段
预期用途如下:
(生成回音“(“hi”“ping”“pong”)=>;一个函数列表,每个函数都会说出它们的名字,就像上面的HELLO一样。您的代码可以简化,并变得更正确,如下所示:
(defmacro generate-echoers (list)
`(progn ,@(loop :for var :in list
:collect `(defun ,(intern (format nil "~:@(~A~)" var)) ()
(format t ,(concatenate 'string var "~&"))))))
首先,您必须将循环的结果拼接到生成的主体中
您还忘记了,concatenate
接受类型参数并对所有变量进行升格(否则您将获得函数名,如|foo |
)。如果将符号传递给generate Echors宏(而不是字符串),则不再需要intern调用:
(defmacro generate-echoers (&rest echoers)
`(progn
,@(mapcar (lambda (var)
`(defun ,var ()
(format t ,(format nil "~(~a~)~&" var))))
echoers)))
要生成的函数:
(defun hello ()
(format t "hello~&"))
我首先编写一个函数,创建上述代码:
(defun make-echoers (name)
`(defun ,(intern (string-upcase name)) ()
(format t ,(concatenate 'string name "~&"))))
请注意,在公共Lisp中,符号默认为大写-因此我们也使用大写
然后您可以测试它:
CL-USER 1 > (make-echoers "hello")
(DEFUN HELLO NIL (FORMAT T "hello~&"))
工作。现在让我们使用它:
(defmacro generate-echoers (list)
`(progn ,@(mapcar #'make-echoers list)))
测试它:
CL-USER 2 > (macroexpand-1 '(generate-echoers ("hi" "ping" "pong")))
(PROGN
(DEFUN HI NIL (FORMAT T "hi~&"))
(DEFUN PING NIL (FORMAT T "ping~&"))
(DEFUN PONG NIL (FORMAT T "pong~&")))
`(progn@(loop
为我解决了它。剩下的我自己整理好了。非常感谢!函数的名称需要是SYMBOL或一个根据Hyperspec的列表。我不理解列表部分,我认为它必须是可设置的。我传递了一个字符串列表。我打赌你传递了一个符号列表?而且,我喜欢mapcar。比loop h干净得多有趣的是,我没有想到使用defun来生成defun。问题已经解决了,但是+1!为thread necro表示歉意;是否可以更改它,以便传递一个值为list的符号(“hi”“ping”“pong”)
,而不是直接传递列表?我尝试使用,list
,但失败。@詹姆斯·波特:您需要确保检索到符号值。例如,更改宏以检查符号并尝试检索符号值。打开另一罐蠕虫。。。