代码之家  ›  专栏  ›  技术社区  ›  John Thomas

使用列表作为lambda方案/球拍的参数名称

  •  1
  • John Thomas  · 技术社区  · 11 年前

    我正在计划中做一个计划评估员。我需要实现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))的计算结果是一个变量名列表(例如:'(x y)),所以我基本上是这样计算的:

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

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

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

    1 回复  |  直到 11 年前
        1
  •  1
  •   Óscar López    11 年前

    要实现 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)
    
    推荐文章