Рассмотрим эти две похожие процедуры:
(define (append-internal-cons obj)
(let ((local-var (cons 1 '()) ))
(append! local-var (list obj))
local-var))
(define (append-internal-no-cons obj)
(let ((local-var '(1) ))
(append! local-var (list obj))
local-var))
Учитывая эти две вспомогательные процедуры:
(define (append! x y)
(set-cdr! (last-pair x) y)
x)
(define (last-pair ls)
(if (null? (cdr ls))
ls
(last-pair (cdr ls))))
Вызов первого из них три раза дает ожидаемые результаты: список, содержащий 1
и любое obj
, которое мы передали.
(append-internal-cons 2) ;; (1 2)
(append-internal-cons 3) ;; (1 3)
(append-internal-cons 4) ;; (1 4)
Я бы ожидал, что вызов второй версии три раза даст те же результаты, но это не так.
(append-internal-no-cons 2) ;; (1 2)
(append-internal-no-cons 3) ;; (1 2 3)
(append-internal-no-cons 4) ;; (1 2 3 4)
Разве поведение двух процедур не должно быть одинаковым?
'(1)
, поэтому это нарушение может даже изменить другие места. Большинство реализаций не сигнализируют об ошибке, поскольку это не требуется, поэтому вы получаете неожиданное поведение от программы, не относящейся к схеме (код, который нарушает отчет, не является кодом схемы) - person Sylwester   schedule 28.05.2016