0
votes

It's a problem in SICP book ch4,here is the code

(let ((a 1))
  (define (f x)
    (define b (+ a x))
    (define a 5)
    (+ a b))
  (f 10))

the error message is “a: undefined; cannot use before initialization”,if I use lambda expression

((lambda (a)
  (define (f x)
    (define a 5)
    (define b (+ a x))
    (+ a b))
  (f 10)) 1)

still dont work,but if I write this as procedure define,like this

(define (f a)
  (define (g x)
    (define b (+ a x))
    (+ a b))
  (g 10))
(f 1)

it runs without error,but these two are basically the same right? why the let and lambda expression failed? thanks.

1

1 Answers

0
votes

Because it refers to the inner a, not the one in the let:

(let ((a 1))
  (define (f x)
    (define b (+ a x))   ; `a` here refers to
    (define a 5)         ;    **this one**
    (+ a b))
  (f 10))

Internal defines are all placed in one shared scope. It is done so we can define mutually recursive functions.

If you switch the order of the two defines it'll work (put a definition above the b definition) because then a will be initialized before being used in the b initialization, but only if you use #lang racket.

In #lang sicp the following works:

(let ((a 1))
  (define (f x)
    (define a 5)
    (define b (lambda () (+ a x)))
    (+ a (b)))
  (f 10))