Схема, SICP, R5RS, почему задержка не является специальной формой? - PullRequest
8 голосов
/ 10 апреля 2011

Это касается главы 3.5 из SICP, в которой обсуждаются потоки. Идея в том, что:

(cons-stream 1 (display 'hey))

Не следует оценивать вторую часть cons-потока, поэтому он не должен печатать «эй» Это происходит, я получаю следующий вывод:

эй (1. # <Обещание>)

Итак, мой вывод, что задержка не реализована в виде специальной формы? Или я что-то не так делаю? Я использую следующую реализацию:

(define (cons-stream a b) 
  (cons a (delay b)))

С задержкой, являющейся реализацией R5RS по умолчанию. Это ошибка в реализации, или я не делаю или не понимаю это правильно?

1 Ответ

15 голосов
/ 10 апреля 2011

Вы выполняете создание обещания, но обещание создается внутри вашего cons-stream, что означает, что уже слишком поздно, и выражение уже было оценено. Попробуйте это:

(define (foo x)
  (display "foo: ") (write x) (newline)
  x)

(cons-stream 1 (foo 2))

и вы увидите, что оно оценивается слишком рано. По той же причине это:

(define ones (cons-stream 1 ones))

и любой другой бесконечный список не будет работать, если ваш cons-stream является функцией. Дело в том, что delay - это особая форма, но вы не используете ее функцию, поскольку определяете cons-stream как простую функцию. Вы должны определить cons-stream как макрос, если хотите, чтобы он также вел себя так же. Например:

(define-syntax cons-stream
  (syntax-rules ()
    [(cons-stream x y) (cons x (delay y))]))
...