【问题标题】:Why doesn't application of function returned by elisp macro work?为什么 elisp 宏返回的函数的应用不起作用?
【发布时间】:2011-06-21 22:55:24
【问题描述】:

例如,这里有一个宏:

(defmacro my-macro (x y)
  (if (> x 0) 
  `(lambda (z) (+ z ,y))
`(lambda (z) (+ ,x z))))

(my-macro 2 3) 返回(lambda (z) (+ z 3))

但是,((my-macro 2 3) 1) 返回一个错误提示,

 Debugger entered--Lisp error:

 (invalid-function (my-macro 2 3))
  ((my-macro 2 3) 1)
  eval(((my-macro 2 3) 1))
  eval-last-sexp-1(nil)
  eval-last-sexp(nil)
  call-interactively(eval-last-sexp nil nil)

我错过了什么?

【问题讨论】:

标签: emacs macros elisp


【解决方案1】:

Emacs Lisp 要求列表的第一个元素form 是内置函数(或subr)、lambda-expression(即(lambda LIST . LIST))或macro lambda-expression(即(macro lambda LIST . LIST)) .第一个元素也可以是symbol,其函数槽包含有效的第一个元素。

(my-macro 2 3) 没有所需的形式,所以它是一个无效的函数。

如果您习惯于 Scheme,其中函数调用的函数部分被正常评估,请注意,这在 Lisp 中无法相同地工作,其中函数具有不同的命名空间((f 3) 查找 f's函数槽,而f 的值通常是它的值槽)。

如果您想像普通值一样评估函数,可以使用funcall or apply

(funcall (my-macro 2 3) 1)

【讨论】:

    【解决方案2】:

    正如错误消息所表明的那样,在评估 ((my-macro 2 3) 1) 表单时,Emacs 在评估它是第一个元素的列表之前不会扩展 (my-macro 2 3)。你想说

    (funcall (my-macro 2 3) 1)
    

    (eval (list (my-macro 2 3) 1)
    

    或类似的东西,以便对宏进行评估。

    【讨论】:

      猜你喜欢
      • 2017-09-23
      • 1970-01-01
      • 1970-01-01
      • 2021-09-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-14
      • 2016-11-08
      相关资源
      最近更新 更多