1

我正在研究方案中的方案评估器。我需要实现 let,我已经解析了变量名、要输入的值和函数体。我需要使用解析的信息返回一个 lambda 函数,因此我有以下代码:

(define (eval-let exp env)
  ((lambda (let-variables (let-bindings exp)) (let-body exp)) (let-exp (let-bindings exp))))

(let-variables (let-bindings exp)) 评估为变量名列表(例如:'(xy)),所以我基本上是在评估这个:

((lambda '(x y) (* x y)) '(2 3))

方案解释器简单地说: #%plain-lambda: not an identifier in: (let-bindings exp) 我猜是因为它需要一组标识符,而不是值列表。

如何将我的值列表转换为一组标识符?

4

1 回答 1

1

要首先在您自己的解释器中实现let表达式,您必须将其转换为lambda应用程序,类似于此(过程名称应该是不言自明的):

(define (let->combination exp)
  (let* ((bindings (let-bindings exp))
         (body     (let-body exp))
         (exps     (bindings-all-exps bindings))
         (lambda   (make-lambda (bindings-all-vars bindings) body)))
    (make-application lambda exps)))

(define (make-lambda parameters body)
  (list* 'lambda parameters body))

(define (make-application proc . args)
  (cond ((null? args) (list proc))
        ((list? (car args)) (cons proc (car args)))
        (else (cons proc args))))

执行语法转换后,您可以继续评估它:

(eval (let->combination exp) env)

我要指出的是,您不应该尝试直接评估它。还要小心,您生成的代码有几个不正确的引号:

((lambda '(x y) (* x y)) '(2 3))
         ^               ^
       here            here

它应该看起来像这样:

((lambda (x y) (* x y)) 2 3)
于 2014-03-30T23:42:52.250 回答