Вопрос

Я имею опыт работы с императивами, но в эти дни пробую свои силы в LISP (Common LISP)

Я читал здесь о нас cons это

(минусы x L):

Учитывая объект LISP x и список L, вычисление (cons x L) создает список, содержащий x, за которым следуют элементы из L.

Когда я намеренно не использовал список в качестве второго аргумента, т.е. когда я использовал

(cons 'a 'a) Я ожидал ошибки, но ого!Я получил (A . A).

Что я пропустил и что такое (A . A)?

Это было полезно?

Решение

Cons создает "ячейку cons".На первый взгляд, это не имеет никакого отношения к спискам.Ячейка 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, у вас есть удобное значение sentinel, и ВСЕ ваши ценности заключаются в cars:

+-----+-----+       +-----+-----+       +-----+-----+       +-----+-----+
|  A  |   --------> |  B  |   --------> |  C  |   --------> |  D  | NIL |
+-----+-----+       +-----+-----+       +-----+-----+       +-----+-----+

Вот как создается список в Lisp.С тех пор как (A . (B . (C . (D . NIL)))) немного громоздкий, он также может быть представлен просто как (A B C D). NIL также называется пустым списком ();это взаимозаменяемые обозначения для одного и того же объекта.

Теперь вы можете понять, почему (cons x list) возвращает другой список. Cons просто создает другую ячейку cons с помощью x в car и ссылка на list в cdr:

+-----+-----+
|  X  |   --------> list
+-----+-----+

и если list является (A B), это работает следующим образом:

+-----+-----+       +-----+-----+       +-----+-----+
|  X  |   --------> |  A  |   --------> |  B  | NIL |
+-----+-----+       +-----+-----+       +-----+-----+

Итак, (cons x '(a b)) оценивает до (x a b).

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

Другие советы

'a атом Лисс и (A . A) это вырожденный список называется Минусы клетки или «пунктирная пара». Так как вы не проходили список для аргумента L в (cons x L) Вы вернулись клетку.

(Минусы х л)

Учитывая x и l, минусы возвращает новую минусную клетку с x как автомобиль этой клетки и l в качестве CDR этой клетки.

Списки связаны цепи мировых клеток.

CL-USER 141 > (sdraw '(a b c))

[*|*]--->[*|*]--->[*|*]---> NIL
  |        |        |
  v        v        v
  A        B        C

CL-USER 142 > (sdraw (cons 'foo '(a b c)))

[*|*]--->[*|*]--->[*|*]--->[*|*]---> NIL
  |        |        |        |
  v        v        v        v
 FOO       A        B        C

Если минусы получают два символа в качестве аргумента, похоже на это:

CL-USER 143 > (sdraw (cons 'foo 'bar))

[*|*]---> BAR
  |
  v
 FOO
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top