所以,我正在通过SICP工作。 第4章的第一次练习是:
练习4.1。请注意,我们无法判断metacircular评估器是从左到右还是从右到左评估操作数。它的评估顺序是从底层的Lisp继承的:如果值列表中的cons的参数是从左到右计算的,那么值列表将从左到右评估操作数;如果从右到左评估cons的参数,那么值列表将从右到左评估操作数。 编写一个值列表的版本,从左到右评估操作数,而不管底层Lisp中的评估顺序如何。还要写一个版本的值列表,从右到左计算操作数。
原始功能是
(define (list-of-values exps env)
(if (no-operands? exps)
'()
(cons (eval (first-operand exps) env)
(list-of-values (rest-operands exps) env))))
我的解决方案如下:
;;; left-to-right
(define (list-of-values-l2r exps env)
(if (no-operands? exps)
'()
(let ((first-exp (eval (first-operand exps) env)))
(cons first-exp
(list-of-values-l2r (rest-operands exps) env)))))
;;; right-to-left
(define (list-of-values-r2l exps env)
(list-of-values-l2r (reverse exps) env))
但是,我不确定我所做的事情是否正确。我的直觉是let语句强制eval,任何人都可以确认吗?
答案 0 :(得分:3)
let
只是语法糖,没有let
的重写看起来像
(define (list-of-values-l2r exps env)
(if (no-operands? exps)
'()
((lambda (first-exp)
(cons first-exp
(list-of-values-l2r (rest-operands exps) env)))
(eval (first-operand exps) env))))
由于方案在评估中非常渴望,因此在应用函数之前始终会评估(eval (first-operand exps) env)
。