1

我正在尝试使用一个函数来返回一个普通 lisp 中的函数。但是,我遇到了一个奇怪的情况,我想解释一下。

这就是我想要做的:

(defun makefun(x) ;1
  (lambda (z)
    (+ x z)))

((makefun 1) 2) ;2

这会导致非法函数调用。但是,以下内容是有效的:

((lambda (z) (+ 1 z)) 2) ;3

(funcall (makefun 1) 2) ;4

为什么我不能像第一个例子那样使用 makefun ?我希望对 2 中的调用进行评估,因此它相当于第 3 行。

4

2 回答 2

4

Common Lisp 有几个不同的命名空间,在函数形式中,使用了操作符的函数值。您的lambda示例有效,因为lambda 表单是评估规则中的一个单独分支。你可以在谷歌上搜索“Common Lisp namespaces”“Lisp-1 vs. Lisp-2”了解更多细节,这里有很多关于这些主题的问题和答案。

但是,要回答您的特定问题,请使用funcall(您也可以查看apply):

(funcall (makefun 1) 2)
于 2013-01-07T22:42:54.673 回答
4

如果已经在 Stackoverflow 上回答了类似的问题。这是一个副本。需要找到它。

反正。

(defun makefun(x) ;1
  (lambda (z)
    (+ x z)))

((makefun 1) 2)

Common Lisp 不允许在函数位置求值。它要求您在其中放置一个符号或实际的 lambda 表达式。

记住:Common Lisp 有一个单独的函数命名空间值命名空间不同。这里MAKEFUN返回一个值,该值在函数命名空间中不可用。

调用函数只有两种语法方式:

(foo 1 2)

((lambda (a b) (list a b)) 1 2)

参见CLHS(Conses as Forms)。这里我们有一个Lambda Form

添加编写能力((some-function-returning-function) 1 2)会使 Common Lisp 中的函数调用更加混乱:

  • (foo 1 2)将使用函数命名空间
  • ((some-function-returning-function) 1 2)将使用值命名空间
于 2013-01-07T22:56:08.183 回答