Scheme 方案:内部定义顺序
这是SICP手册ch4中的一个问题,下面是代码Scheme 方案:内部定义顺序,scheme,Scheme,这是SICP手册ch4中的一个问题,下面是代码 (let ((a 1)) (define (f x) (define b (+ a x)) (define a 5) (+ a b)) (f 10)) 如果使用lambda表达式,则错误消息为“a:未定义;无法在初始化之前使用” ((lambda (a) (define (f x) (define a 5) (define b (+ a x)) (+ a b)) (f 10)) 1)
(let ((a 1))
(define (f x)
(define b (+ a x))
(define a 5)
(+ a b))
(f 10))
如果使用lambda表达式,则错误消息为“a:未定义;无法在初始化之前使用”
((lambda (a)
(define (f x)
(define a 5)
(define b (+ a x))
(+ a b))
(f 10)) 1)
仍然不起作用,但是如果我把它写成过程定义,像这样
(define (f a)
(define (g x)
(define b (+ a x))
(+ a b))
(g 10))
(f 1)
它运行没有错误,但这两个基本上是一样的,对吗?为什么let和lambda表达式失败?谢谢。因为它指的是内部的
a
,而不是let
中的那一个:
(let ((a 1))
(define (f x)
(define b (+ a x)) ; `a` here refers to
(define a 5) ; **this one**
(+ a b))
(f 10))
内部define
s都放在一个共享范围内。这样我们就可以定义相互递归的函数
如果您切换两个define
s的顺序,它将起作用(将a
定义置于b
定义之上),因为a
将在b
初始化中使用之前进行初始化,但仅当您使用#lang racket
时
在#lang sicp
中,以下作品:
(let ((a 1))
(define (f x)
(define a 5)
(define b (lambda () (+ a x)))
(+ a (b)))
(f 10))
您好,正如您所说,我将a定义置于b定义之上,但它仍然显示相同的错误(我使用#lang sicp在DrRacket中编写此代码)刚刚检查了
#lang sicp
,它确实抛出了一个错误。我想这是遵循了lang r5rs在这方面的领导。嵌套定义在共享的letrec
中有效,在R5R中,在初始化期间禁止引用letrec变量的值。好吧……一个愚蠢的问题,为什么在b定义中,解释器在let(A1)中找不到a?我真的很困惑,谢谢你帮助我,因为你定义它引用a
,在内部范围中有一个a
,与b
定义的范围相同。把这段代码放到Dr Racket中,用鼠标悬停变量,它会画出漂亮的箭头来显示哪个变量引用了什么定义。所以内部定义是同时计算的,而不是按顺序计算的,对吗?