【问题标题】:Cannot use function call as first argument in s-exp [duplicate]不能将函数调用用作 s-exp 中的第一个参数 [重复]
【发布时间】:2012-12-21 16:44:51
【问题描述】:

我正在尝试使用一个函数来返回一个普通 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 行。

【问题讨论】:

    标签: lambda lisp common-lisp


    【解决方案1】:

    如果已经在 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) 将使用值命名空间

    【讨论】:

      【解决方案2】:

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

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

      (funcall (makefun 1) 2)
      

      【讨论】:

        猜你喜欢
        • 2020-08-28
        • 1970-01-01
        • 2018-01-09
        • 1970-01-01
        • 2016-11-19
        • 2017-12-12
        • 1970-01-01
        • 2022-01-13
        • 1970-01-01
        相关资源
        最近更新 更多