如何解决Lisp - 在宏中使用逗号 (`,`)
我正在练习用 Elisp 编写宏。老师建议我们将程序的宏部分包含在“quasiquote”中。
我想写一个宏“printCdrEach”来打印列表中cdr的每个元素(仅供练习)
(defmacro print-cdr-each (first &rest rest)
`(while (not (null,rest))
(eval (car,rest))
(setq rest (cdr,rest)))
)
(print-cdr-each 1 2 3 4) ; Expected Output 2 3 4
我不断收到错误“无效函数:2”。我确信编译器认为 2
是一个函数。但是,我不确定如何修复此程序。
在不更改输入格式 (printCdrEach x x x x)
的情况下,在我的程序中适当使用“,”以使其正常工作?
解决方法
你应该试试macroexpand-1
:
(macroexpand-1 '(print-cdr-each 1 2 3 4))
; ==> (while (not (null (2 3 4)))
; (eval (car (2 3 4)))
; (setq rest (cdr (2 3 4))))
; ==> t
- 表达式
(2 3 4)
无效。在 REPL 中试试,你会得到eval: 1 is not a function name
- 您多次使用
rest
,因此如果它是一个表达式,它将被计算多次。
真的不需要宏:
(defun for-each (operation &rest elements)
(loop :for e :in elements
:do (funcall operation e)))
(for-each #'print 10 20)
10
20
; ==> nil
宏是语法糖。这意味着你应该能够说什么
(print-cdr-each 1 2 3 4)
应该在代码中扩展为。由于您将其作为宏执行,因此您可能希望将其扩展为静态:
(defmacro for-each (operation &rest elements)
`(progn,@(loop :for e :in elements
:collect `(,operation,e))))
(macroexpand-1 '(for-each print a b))
; ==> (progn (print a) (print b))
; ==> t
(let ((a 10) (b 20)) (for-each print a b))
10
20
; ==> 20
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。