【问题标题】:Why aren't the function values being passed to the lambda function and evaluating?为什么不将函数值传递给 lambda 函数并进行评估?
【发布时间】:2017-03-03 03:57:57
【问题描述】:

所以我正在尝试构建一个解释器来处理用户定义的 lambda 函数,这些函数可以有可变数量的参数。代码看起来有点像这样:

((lambda (x &optional y z) (func_body)) args))

现在,我可以得到的结果是正确的函数,而无需对其进行评估;例如,如果我定义 square X = (* X X) 并运行我的解释器,我会得到:

(* X X)

我需要的是经过评估后的上述功能。我试过这样的事情:

(let ((func (lambda (x &optional y z) (func_body))))
     (apply/funcall func args))

((lambda (x &optional y z) (func_body)) args)

但是,它们仍然会产生我不想要的结果。我试图拥有它,所以当我定义square X = (* X X) 并输入(square 4) 时,我得到:

16

关于我缺少什么的任何指导?

编辑:args 子句由(cdr/car Y) 或其他函数生成。另外,如果我尝试使用函数 lisp 生成 lambda 列表,抱怨它不是符号,知道为什么会这样吗?

【问题讨论】:

    标签: lambda lisp


    【解决方案1】:

    我看到的唯一错误是let 的语法:应该是

    (let ((func (lambda (x) (* x x))))
      (funcall func 4))
    ==> 16
    

    Lambda 也可以:

    ((lambda (x) (* x x)) 5)
    ==> 25
    

    现在,如果你的身体存储在variable 中,它会变得稍微做作:

    (defparameter *square* '(* x x))
    (funcall (coerce `(lambda (x) ,*square*) 'function) 3)
    ==> 9
    

    但是,从一开始就将您的代码保留为lambda 会更好:

    (defparameter *square* (lambda (x) (* x x)))
    (funcall *square* 4)
    ==> 16
    

    【讨论】:

    • 我应该提到 args 子句是由 (cdr/car Y) 或其他函数生成的。大部分 lambda 函数都是我现在想到的。基本上,命令行读取类似于>'square X = (* X X) 'square 4 结果:> 16
    • 非常感谢!
    【解决方案2】:

    ((lambda (x &optional y z) (func_body)) args)

    例子:

    CL-USER 111 > ((lambda (x &optional (y 0) (z 0))
                     (+ x y z))
                   1
                   2
                   3)
    6
    
    CL-USER 112 > (apply (lambda (x &optional (y 0) (z 0))
                           (+ x y z))
                         '(1 2 3))
    6
    

    【讨论】:

      【解决方案3】:

      在创建不依赖主机 eval (coerce) 的解释器时,您将 lambda 与当前环境一起存储为数据。您的apply 需要支持创建一个新框架,其参数绑定到基于存储环境的名称。然后需要在那个环境下评估身体。因此,您永远不会将 Common Lisp lambda 宏而不是 apply 用于复合应用程序。

      建议使用coerce 的其他答案不适用于解释器中的词法变量。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-09-03
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多