【问题标题】:how to return function in elisp如何在elisp中返回函数
【发布时间】:2013-05-02 17:23:09
【问题描述】:

这和这个问题有关:elisp functions as parameters and as return value

(defun avg-damp (n)
   '(lambda(x) (/ n 2.0)))

要么

(funcall (avg-damp 6) 10)

((avg-damp 6) 10)

他们分别给出了Symbol's value as variable is void: neval: Invalid function: (avg-damp 6)的错误。

【问题讨论】:

  • 请不要引用您的 lambda。除此之外,您的示例将在最近的 Emacs 中工作,前提是您在将 lexical-binding 设置为 t 的缓冲区中执行此操作。

标签: function lisp return elisp


【解决方案1】:

第一种形式不起作用的原因是n 是动态绑定的,而不是词法绑定的:

(defun avg-damp (n)
  (lexical-let ((n n))
    (lambda(x) (/ x n))))
(funcall (avg-damp 3) 12)
==> 4

第二种形式不起作用的原因是 Emacs Lisp 和 Common Lisp 一样,a "lisp-2", not a "lisp-1"

【讨论】:

  • 请注意:lisp-1 和 lisp-2 之间的区别在于符号是否只有值绑定(lisp-1)或值绑定和函数绑定。 lisp-2 仍然可以有一个求值语义,表示“求值 (f a1 a2 ...),如果 f 是一个符号,应用它的函数绑定到 a1 a2 ...,否则如果 f 是一个复合形式,求值并应用结果为 a1 a2 ..."。在 Common Lisp 中,我们已经可以做到 ((lambda (x) (list x x)) 4) 并得到 (4 4)。我认为支持 ((...) ...) 的 lisp 仍然可以是 lisp-2,只要 (f ...) 仅应用 f 的函数绑定,而不是值绑定。
  • @JoshuaTaylor ((lambda (...)...) ...) 是 Cl 中的一个特例。通常,每当您评估函数时,您都会获得值“绑定”(嗯,值),但(lambda (...) ...) only 具有函数“值”而不是一般值,因此它已被明确允许.
  • @Vatine 绝对正确。如果没有 CL 那种特殊情况,我们会 (let ((f (lambda (…) …))) (apply f …)) 就像我们对非lambda 表格所做的那样。不过,我的观点是,函数位置中的非符号、函数生成形式从根本上不需要任何修改来分离函数和值命名空间。 (在 CL 中,其他东西(例如,符号宏)可能会导致问题。)如果某些 lisp 在函数位置允许非符号、函数生成形式,并且具有单独的函数和值命名空间,我会更倾向于调用它lisp-2 比 lisp-1。
  • 有没有办法在没有 funcall 的情况下调用这个函数:例如 (#'(avg-dump 5) 10)。除了 funcall,我找不到任何其他方法。看起来有点丑。
  • @yilmazhuseyin:没有。您将不得不使用funcallapply
猜你喜欢
  • 2013-05-09
  • 1970-01-01
  • 1970-01-01
  • 2010-10-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-14
相关资源
最近更新 更多