【问题标题】:Using a list as argument names for lambda scheme/racket使用列表作为 lambda 方案/球拍的参数名称
【发布时间】:2014-05-10 04:14:18
【问题描述】:

我正在制定一个方案评估器。我需要实现 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: not an identifier in: (let-bindings exp) 我猜是因为它需要一组标识符,而不是值列表。

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

【问题讨论】:

    标签: scheme racket lambda let evaluator


    【解决方案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)
    

    【讨论】:

    • “尝试直接评估”才是正轨。我忘记了我已经有一个申请程序,基本上将这些东西作为列表接收。谢谢!
    • 太棒了!这是我的荣幸:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-02-03
    • 2022-07-27
    • 1970-01-01
    • 2023-03-23
    • 2011-10-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多