Scheme - Lambda 作为一个坏的函数对象

Scheme - Lambda as a Bad Function Object

我正在为作业编写 Scheme 中的元循环求值器,我需要允许用户通过将特殊表单添加到 table 来安装它们。这个想法是,当用户输入类似 (square 5) 的内容时,评估器将查找名为 square 的表单。如果找到,它将 return 一个 lambda 语句,类似于 (lambda (x) (* x x)).

当代码 return 是 lambda 语句时,我遇到了问题。我收到以下错误消息:

Error: Bad function object:(lambda (x) (* x x))

真正奇怪的是我可以将参数传递给从我的 table 检索到的函数,只是我必须事先将过程主体定义为 lambda 语句,而不是以 [ 开头的列表=15=]

供参考,下面是不起作用的代码。 exp 类似于 (install-special-form 'square (lambda (x) (* x x))),因此在这种情况下,name 的计算结果为 squarefunc 的计算结果为 (lambda (x) (* x x)):

(define (install-eval exp)
  (define name (cadadr exp))
  (define func (caddr exp))
    (if (special-form-lookup (list name func))
        #f
       (begin
         (append! special-forms-table (list name func))
         name)))

下面是一些有效的代码:

(define (install exp-list)
  (append! special-forms-table exp-list))
(install (list 'square (lambda (x) (* x x))))

我猜我的问题是,当使用不起作用的代码时,lambda 被评估为引号,而不是实际的 lambda?如何让我的用户输入存储可以检索和使用的实际 lambda 语句?

您可能将 lambda 存储为符号列表,而不是实际过程。这就是为什么这行不通的原因:

(define f '(lambda (x) (* x x)))
(f 10)
=> Error: Bad function object: (lambda (x) (* x x))

首先尝试评估它:

((eval f) 10)
=> 100

当您 return list (lambda (x) (* x x)) 时,您不能将它应用于主机,因为它就像 ('(lambda (x) (* x x)) 5)。试试吧。你会得到同样的错误。

当 Scheme 对特殊形式 (lambda (x) (* x x)) 求值时,它 return 是一个闭包 object 与创建时的环境。当您调用它时,它将 运行 body 与那个环境一起添加 bingind 到 x。这需要在您的解释器中进行模拟,因此通常 (lamba (args ...) body) 通常被评估为 (closure-tag (args ...) environment body)。您的申请需要这些才能在正确的环境下在 body 上调用 eval。 Oscars 使用 eval 的建议不会在很长的 运行 中起作用,因为您将无法使用 eval 在解释器中进行闭包,如果您确实得到了,我会认为它作弊远离它。