define
делает переменную.Имя, которое оценивает местоположение объекта.
(define foo (list 'a 'b))
Здесь foo
может указывать на адрес 240
.При оценке foo
вы получаете 240
назад, поэтому (define bar foo)
создаст вторую переменную, которая указывает на тот же объект в памяти.Адреса не отображаются в REPL, поэтому вы увидите (a b)
, поскольку REPL печатает адрес по адресу 240
.
Этот объект в памяти является cons
, поэтому каждый из них - всего два указателя на другие значения в памяти.Таким образом, когда вы делаете:
(set-car foo 'c)
, вы меняете минусы, расположенные по адресу 240, изменяя указатель car
с адресного представления a
на адресное представление c
.Так как foo
и bar
указывают на одну и ту же конс-ячейку по адресу 240
, они оба получат изменение, поскольку они указывают на одинаковые данные .
Если вы используете set!
вы меняете только то значение, на которое указывает имя:
(set! foo (cons 'd (cdr foo)))
Теперь это изменит указатель на переменную, указав на 240
другой адрес.Таким образом, вы можете оценить foo
и bar
и увидеть, что это разные значения:
foo ; ==> (d b)
bar ; ==> (c b)
Здесь foo
может находиться в адресе 256
.Поскольку мы использовали старые значения cdr
в foo
, мы знаем, что их хвосты одинаковы:
(cdr foo) ; ==> (b)
(eq? (cdr foo) (cdr bar)) ; ==> #t
Если вам set!
bar
присвоить другое значение:
(set! bar foo)
Теперь и foo
, и bar
указывают на 256
, и если больше не используется 240
, пара в этом месте может быть подвергнута сборке мусора, но с cdr
оригинального foo
это cdr
, скажем, адрес 248
, этот адрес не будет собирать мусор, так как на него указывает cons
в адресе 256
.
Примечание: я изменил определение foo
, поскольку вам не разрешено использовать set-car
литералы, такие как '(a b)
, поскольку они неизменяемы.(list 'a 'b)
создает новый список каждый раз, когда выполняется строка кода, и вы можете быть уверены, что адрес не используется повторно, например.'(d a b)
.
NB2. В отчете по схеме стараются не указывать, как хранить значения.Таким образом, они не используют адрес концепции в отчете.Большинство реализаций как Scheme, так и CL моделируют свои данные довольно схожими.