Неожиданный вывод с cons ()

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

Я прочитал здесь о cons этом

(cons x L):

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

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

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

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


person Prasoon Saurav    schedule 14.08.2010    source источник


Ответы (3)


Cons создает «cons-ячейку». Поначалу это не имеет никакого отношения к спискам. Консольная ячейка - это пара двух значений. Консольная ячейка представлена ​​в письменной форме «пунктирной парой», например (A . B), который содержит два значения 'A и 'B.

Два места в cons-ячейке называются car и cdr. Вы можете визуализировать такую ​​cons-ячейку как разделенный пополам блок:

  car   cdr
+-----+-----+
|  A  |  B  |
+-----+-----+

В Лиспе значение также может быть ссылкой на что-то еще, например, на другую cons-ячейку:

+-----+-----+       +-----+-----+
|  A  |   --------> |  B  |  C  |
+-----+-----+       +-----+-----+

Это будет представлено в виде «пары точек» как (A . (B . C)). Вы можете продолжить так:

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

Это (A . (B . (C . D))). Как видите, в такой структуре значения всегда находятся в car cons-ячейки, а cdr указывает на остальную часть структуры. Исключение составляет последнее значение, которое находится в последнем cdr. Однако нам не нужно это исключение: в Лиспе есть специальное значение NIL, которое обозначает «ничего». Помещая NIL в последний cdr, вы получаете удобное контрольное значение, а все ваши значения находятся в cars:

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

Так строится список в Лиспе. Поскольку (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-ячеек, круговых списков или любого ориентированного графа.

person Svante    schedule 14.08.2010

'a - это атом лиспа, а (A . A) - вырожденный список, называемый cons-ячейкой или "пунктирной парой". . Поскольку вы не передали список для аргумента L в (cons x L), вы вернули ячейку.

person msw    schedule 14.08.2010

(МИНУСЫ x L)

Для заданных x и L функция CONS возвращает новую cons-ячейку с x в качестве CAR этой ячейки и L в качестве CDR этой ячейки.

Списки представляют собой связанные цепочки cons-ячеек.

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

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

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

[*|*]---> BAR
  |
  v
 FOO
person Rainer Joswig    schedule 14.08.2010