【发布时间】:2017-10-18 23:06:42
【问题描述】:
我想知道下面的代码如何计算为 3。
(define (foo y) ((lambda (x) y) ((lambda (y)(* y y)) y)))
(foo 3)
我已经看了一段时间,似乎无法理解为什么评估不会导致 9。有人可以提供详细的分步说明,说明如何评估为 3?
【问题讨论】:
标签: scope scheme racket evaluation r5rs
我想知道下面的代码如何计算为 3。
(define (foo y) ((lambda (x) y) ((lambda (y)(* y y)) y)))
(foo 3)
我已经看了一段时间,似乎无法理解为什么评估不会导致 9。有人可以提供详细的分步说明,说明如何评估为 3?
【问题讨论】:
标签: scope scheme racket evaluation r5rs
让我们首先以更容易理解的方式缩进代码:
(define (foo y)
((lambda (x) y)
((lambda (y) (* y y))
y)))
现在让我们从内到外评估它:
(define (foo y)
((lambda (x) y)
((lambda (y) (* y y))
3))) ; pass the parameter
(define (foo y)
((lambda (x) y)
(* 3 3))) ; evaluate innermost lambda
(define (foo y)
((lambda (x) y) 9)) ; pass the result of evaluation
啊哈!这就是我们得到3 的地方。即使我们将9 作为参数传递(绑定到x),我们也只是返回最外层y 参数的值,一直是3:
=> 3
【讨论】:
用let重写,
(define (foo y) ((lambda (x) y) ((lambda (y)(* y y)) y)))
(foo 3)
=
(let ([y 3]) ; by application
((lambda (x) y) ((lambda (y)(* y y)) y)))
=
(let ([y 3])
(let ([x ((lambda (y)(* y y)) y)]) ; by application
y ))
=
(let ([y 3])
(let ([x ((lambda (z)(* z z)) y)]) ; by alpha-renaming
y ))
=
(let ([y 3])
(let ([x (let ([z y]) ; by application
(* z z))])
y ))
=
(let ([y 3])
(let ([x (* y y)]) ; by let-elimination
y ))
=
(let ([y 3])
(let ([x 9]) ; by expression evaluation
y ))
=
(let ([y 3])
y ) ; by let-elimination
=
3 ; by let-elimination
如您所见,嵌套的(lambda (y)(* y y))位于嵌套范围内,不会影响最终返回的y,而只会影响x,其值9是评估然后丢弃。
【讨论】: