Неожиданный вывод с недостатками ()

Я обязательного происхождения, но в эти дни пробуя мои руки на LISP (язык Common LISP)

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

(недостатки x L):

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

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

(cons 'a 'a) Я ожидал ошибку, но стоп! Я добрался (A . A).

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

11
задан Prasoon Saurav 14 August 2010 в 06:55
поделиться

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))) . Как вы можете видеть, в такой структуре значения всегда находятся в машине 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 просто создает другую cons-ячейку с x в car и ссылкой на список в cdr :

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

и если список равен (AB) , он работает как:

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

Итак, (cons x '(ab)) оценивается как (xab) .

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

7
ответ дан 3 December 2019 в 10:24
поделиться

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

1
ответ дан 3 December 2019 в 10:24
поделиться

(CONS 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
1
ответ дан 3 December 2019 в 10:24
поделиться