Cons
создает «клетку против».Поначалу это не имеет ничего общего со списками.Минус ячейка - это пара двух значений.Cons-ячейка представлена в письменной форме «пунктирной парой», например, (A . B)
, которая содержит два значения 'A
и 'B
.
Два места в cons-ячейке называются «car»."и" CDR ".Вы можете визуализировать такую cons-ячейку как разделенный на две части блок:
car cdr
+-----+-----+
| A | B |
+-----+-----+
В Lisp значение также может быть ссылкой на что-то еще, например, на другую cons-ячейку:
+-----+-----+ +-----+-----+
| A | --------> | B | C |
+-----+-----+ +-----+-----+
Это будет представлено в виде «пунктирной пары» как (A . (B . C))
.Вы можете продолжать так:
+-----+-----+ +-----+-----+ +-----+-----+
| A | --------> | B | --------> | C | D |
+-----+-----+ +-----+-----+ +-----+-----+
Это (A . (B . (C . D)))
.Как вы можете видеть, в такой структуре значения всегда находятся в car
в ячейке cons, а cdr
указывает на остальную часть структуры.Исключением является последнее значение, которое находится в последнем cdr
.Нам не нужно это исключение: в Лиспе есть специальное значение NIL
, которое обозначает «ничего».Поместив NIL
в последний cdr
, вы получите удобное значение часового, и все ваши значения будут в car
s:
+-----+-----+ +-----+-----+ +-----+-----+ +-----+-----+
| A | --------> | B | --------> | C | --------> | D | NIL |
+-----+-----+ +-----+-----+ +-----+-----+ +-----+-----+
Вот каксписок построен в Лиспе.Поскольку (A . (B . (C . (D . NIL))))
немного громоздкий, его также можно представить просто как (A B C D)
.NIL
также называется пустым списком ()
;это заменяемые записи для одной и той же вещи.
Теперь вы можете понять, почему (cons x list)
возвращает другой список.Cons
просто создает другую ячейку с x
в car
и ссылкой на list
в cdr
:
+-----+-----+
| X | --------> list
+-----+-----+
, а если list
равно (A B)
, этоработает следующим образом:
+-----+-----+ +-----+-----+ +-----+-----+
| X | --------> | A | --------> | B | NIL |
+-----+-----+ +-----+-----+ +-----+-----+
Таким образом, (cons x '(a b))
оценивается как (x a b)
.
Списки - это всего лишь одно из наиболее распространенных применений cons-ячеек.Вы также можете создавать произвольные деревья из cons-ячеек, круговых списков или любого ориентированного графа.