【问题标题】:Lisp - Utilisation of comma (`,`) in macroLisp - 在宏中使用逗号(`,`)
【发布时间】:2021-05-27 21:12:48
【问题描述】:

我正在练习用 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) 的情况下,在我的程序中正确使用“,”以使其正常工作?

【问题讨论】:

  • 为什么这是一个宏?宏编写的第一条规则是:当函数足够时不要编写宏。可能第二条规则是:除非必须,否则不要使用eval,而且您可能不需要。另外,在 lisps 中更喜欢 kebab-casecamelCase:lispers care ;)
  • 是的,这就是为什么我说它只是为了练习语法,因为我是 Lisp 新手,所以我想开始一些简单的事情。值得注意的是,我不知道 Lisp 中的这种命名约定。谢谢指出
  • 另外,如果我不使用eval,我将如何在这里打印出元素? (restcar)是错误的根源来自我使用eval 的事实吗?
  • (2 3 4) 将代替 ,rest,因此 (car ,rest) 将评估为 2,并且 (eval 2) 不起作用,因为 2 不是函数,因此出现错误信息。您不想使用打印功能代替 eval 吗?
  • @JayK -- (eval 2) 工作正常,因为eval 评估表单。这是错误的做法。 (car ,rest) --> (car (2 3 4))(2 3 4) 尝试使用参数 34 调用函数 2。相反,(car (quote ,rest)) 可能是朝着正确方向迈出的一步。

标签: macros lisp elisp


【解决方案1】:

你应该试试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

【讨论】:

  • 这个问题是基于elisp的,而我认为你的答案是CL。 Elisp 确实有 while。不确定是否有花哨的loop(我敢打赌有一个包......)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-11-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-04-26
  • 1970-01-01
相关资源
最近更新 更多