У меня трудности с упражнением 3.6 в SICP. Они дают следующий код для генератора псевдослучайных чисел:
(define rand
(let ((x random-init))
(lambda ()
(set! x (rand-update x))
x)))
К которому я добавил, для целей тестирования:
(define (rand-update x) (+ x 1))
(define random-init 4)
Повторные приложения производят
> (rand)
5
> (rand)
6
> (rand)
7
как и надеялся, хотя я не понимаю, почему это работает. В любом случае, упражнение 3.6 просит нас изменить rand
так, чтобы он принимал один аргумент, указав 'generate
или 'reset
.
Первым делом я попытался настроить ранд с условиями это будет генерировать. Однако я наткнулся на это первое препятствие.
(define (rand-new instruction)
(let ((x random-init))
(cond ((eq? instruction 'generate)
(lambda ()
(set! x (rand-update x))
x)))))
дает мне
> ((rand-new 'generate))
5
> ((rand-new 'generate))
5
> ((rand-new 'generate))
5
, как и перемещение выражения let в условие, например:
(define (rand-new instruction)
(cond ((eq? instruction 'generate)
(let ((x random-init))
(lambda ()
(set! x (rand-update x))
x)))))
Так почему же первая функция работает, а новая нет? Это связано с использованием условий? Или с добавлением параметра?
ОБНОВЛЕНИЕ (19/03/20)
Чтение следующего раздела по модели вычисления среды (§3.2) дало мне теория, необходимая, чтобы выяснить, что происходит. Я закончил с
(define (random-number-generator initial update)
(define (generate)
(begin (set! initial (update initial))
initial))
(define (reset new-value)
(begin (set! initial new-value)
initial))
(define (dispatch message)
(cond ((eq? message 'generate) (generate))
((eq? message 'reset) reset)
(else "Procedure not found!")))
dispatch)
(define rand (random-number-generator 5 rand-update))