不能将函数调用用作s-exp中的第一个参数

时间:2013-01-07 21:52:36

标签: lambda lisp common-lisp

我正在尝试使用函数来返回常见的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行。

2 个答案:

答案 0 :(得分:4)

Common Lisp有几个不同的namespaces,在function forms中,使用了运算符的functional value。您的lambda示例有效,因为lambda forms是评估规则中的一个单独分支。你可以谷歌搜索" Common Lisp命名空间" " Lisp-1 vs. Lisp-2"有关详细信息,这里有很多问题和答案on SO,涵盖了这些主题。

但是,要回答您的具体问题,请使用funcall(您还可以查看apply):

(funcall (makefun 1) 2)

答案 1 :(得分: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表单

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

  • (foo 1 2)将使用函数名称空间
  • ((some-function-returning-function) 1 2)将使用值命名空间