Разница между Lisp (cons 'a (cons' b 'c)) и (cons' a '(b.c)) - PullRequest
3 голосов
/ 07 декабря 2009

Какая разница между:

(cons 'a (cons 'b 'c)) ;; (A B . C)

и

(cons 'a '(b.c)) ;; (A B.C)

Мне нужно создать следующий список ((a.b) .c), используя cons, поэтому я пытаюсь понять, что это за "." представляет.

L.E. : у меня есть следующее (cons (cons 'a 'b) 'c), но оно выдает ((A . B) . C), а не ((A.B).C) (обратите внимание на дополнительные пробелы)

Ответы [ 3 ]

6 голосов
/ 07 декабря 2009

Пробелы используются для разделения списка токенов. A.B - это один токен. (A.B) - список с одним элементом. (A . B) - это конс-ячейка с A как автомобиль и B как cdr.

Минус ячейка - это пара "вещей" (объектов). В вашем случае это символы, и они называются A, B и т. Д. Печатное представление такой ячейки, например, (A . B). Это называется «точечная нотация». Первый элемент называется «car», второй «cdr».

Функция cons создает такую ​​ячейку. (cons 'a 'b) создает ячейку (A . B). Обратите внимание, что имена всегда заключаются в внутренний регистр .

Скорее всего, этого хотел ваш учитель, поэтому ((A . B) . C) - это правильный вывод, а ваш код - правильный ответ. Это ячейка, в которой автомобиль указывает на другую ячейку, а cdr содержит C. Эта другая ячейка является ячейкой, в которой автомобиль содержит A и cdr B.

Кстати, список представляет собой линейную цепочку таких cons-ячеек, так что автомобиль всегда содержит значение, а cdr указывает на остальную часть списка. Последний cdr нигде не указывает (который в Лиспе называется NIL). В точечной записи список, например, (A . (B . (C . NIL))). Поскольку списки важны, их можно записать так: (A B C). Если последний CDR имеет значение вместо NIL, оно отображается в точечной нотации, например, (A . (B . (C . D)))) можно записать как (A B C . D).

6 голосов
/ 07 декабря 2009

. между двумя символами является частью символа. b.c - это символ с именем из трех символов: b , . и c .

Если вы введете FOO.BAR, тогда Лисп прочитает его как один символ.

Если вы введете (FOO.BAR), тогда Lisp будет читать его как список с одним символом в качестве его содержимого.

Если вы введете (FOO . BAR), тогда Лисп будет читать его как конс-ячейку с FOO как CAR и BAR как CDR .

. используется для разделения CAR и CDR в ячейке cons: (a . b). Обратите внимание на пространство вокруг ..

(cons 'b 'c) создает ячейку с символом b в качестве CAR и символом c в качестве CDR . Это записано как (b . c).

(cons 'a '(b.c)) создает список из двух символов, a и b.c. Это записано как (a b.c).

((A.B).C) всегда печатается как ((A.B) . C). Это тоже не список.

((a.b) . c) - это ячейка с списком (a.b) в качестве CAR и символом c в качестве CDR .

1 голос
/ 07 декабря 2009

Если это происходит в процессе изучения lisp, вопрос, вероятно, не подразумевал подразумеваемое правило «без пробелов», поскольку пробелы не имеют значения для скобок, и правильный ответ - тот, который вы дали.

В частности, пробел после закрывающей скобки всегда добавляется, но только для удобства чтения. Нет смысла требовать, чтобы он не печатался.

...