[英]Using a list as argument names for lambda scheme/racket
我正在研究Scheme中的方案评估器。 我需要实现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:不是(:let-bindings exp)中的标识符,我猜这是因为它想要一组标识符,而不是值列表。
如何将值列表转换为一组标识符?
要首先在自己的解释器中实现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)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.