схема: порядок внутреннего определения - PullRequest
0 голосов
/ 07 марта 2020

Это проблема в SICP book ch4, вот код

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

сообщение об ошибке «a: undefined; не могу использовать перед инициализацией », если я использую лямбда-выражение

((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 и лямбда не сработали? спасибо.

1 Ответ

0 голосов
/ 07 марта 2020

Поскольку это относится к внутреннему 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 все размещены в одном общем Объем . Это сделано для того, чтобы мы могли определять взаимно рекурсивные функции.

Если вы переключите порядок двух define с, это сработает (поместите 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))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...