(set! c (cons 3 c))
Ну, давайте быть ясно, что это выражение делает:
set!
принимает переменную в качестве первого аргумента и выражения в качестве второго аргумента. Он вычисляет второй аргумент и присваивает значение переменной.
cons
принимает значение и список и производит список с заданным значением в качестве главы, а данный список - как его хвост.
Таким образом, (set! c (cons 3 c))
создает список с 3
как головы и c
как хвост, и присваивает этот список в качестве значения c
. Это изменение видимо только для кода, который обращается к той же привязке c
, если есть другие переменные или поля объектов, которые относятся к исходному списку, они по-прежнему относятся к этому исходному списку.
Это можно свободно описать как «добавление элемента в список» в некоторых контекстах, но это свободное описание, потому что вы не берете существующий список и не изменяете его, чтобы иметь новый элемент; скорее, вы создаете список с новым начальным элементом и исходным списком в качестве его хвоста и изменяете примерно (но, возможно, не все) ссылки на старый список, чтобы указать на новый.
Есть две основные вещи, которые я могу думать покинуть сразу, что также может рассчитывать как «добавление элемента в список»:
- Изменение структуры существующего списка, чтобы добавить новую пару где-то в середина или конец. Если вы действительно строго придерживаетесь терминологии, это единственный случай «добавления элемента в список».
- Заканчивает элемент перед списком и возвращает его вызывающему или передает его в качестве аргумента другой функции (без набора!). Это даже более свободный язык, чем ваш пример, но это также самый распространенный случай!
Пример первый:
(define (insert-at-second-position! item list)
(set-cdr! list (cons item (cdr list))))
Пример второй:
(define (list-copy xs)
(if (null? xs)
'()
;; We call list-copy recursively on the tail, and "add an item"
;; at the front:
(cons (car xs)
(list-copy (cdr xs)))))
«cons - это процедура создания пары»: язык программирования схемы, 3-е изд., Стр. 133. http://www.scheme.com/tspl3/objects.html#./objects:h1 – drb