LINUX.ORG.RU

LISP: простой вопрос по cons и list


0

0

В чем разница (и какова) между функциями cons и list в LISP? 
Обе создают список. Вот только, почему-то, выглядят они оба по-разному:

> (cons 'a 'b)
(A . B)

> (list 'a 'b)
(A B)

Что значит эта точка между элементами списка в первом случае?
Эквивалентны ли оба списка? Спасибо.
anonymous

cons создает не список, так называемую cons cell, которая состоит из двух элементов головы (car) и хвоста (cdr).

Аналогом (list 'a 'b) будет (cons 'a (cons 'b nil)). Аналогично для (list 'a 'b 'c) будет (cons 'a (cons 'b (cons 'c nil))).

Думаю, из этих примеров понятно как в лиспе строится списки.

kpanic ★★
()

cons - он принимает пару: голову и хвост списка - и создает список, присоединяя голову (единичный элемент) к хвосту (список элементов).
list - просто собирает в список все свои аргументы.
Т.е.:
> (list 'a '(b c))
(A (B C))

> (cons 'a '(b c))
(A B C)

Точка в (A . B) означает, что голова (A) присоединяется к хвосту списка (B)

rexadecimal
()

> (cdr (cons 'a 'b))
B

> (cdr (list 'a 'b))
(B)

Miguel ★★★★★
()
Ответ на: комментарий от rexadecimal

> cons - он принимает пару: голову и хвост списка - и создает список, присоединяя голову (единичный элемент) к хвосту (список элементов).

Немножко не так. cons принимает в качестве агрументов объекты, на которые будут ссылаться голава и хвост cons cell, которую cons и создает.

Соответсвенно список (list) состоит из цепочек cons-ячеек, хвост (cdr) которых указывает на голову (car) следующей ячейки. Список называется правильным, если хвост последней ячейки указывает на nil. Т.е.

(cons 'a (cons 'b nil))

будет эквивалентен

(list 'a 'b)

Хорошо расписано и удобные для понимания иллюстрации cons-ячеек есть в PCL http://www.gigamonkeys.com/book/they-called-it-lisp-for-a-reason-list-process...

stassats ★★★★
()

> Что значит эта точка между элементами списка в первом случае?

Точка означает, что cdr этой ячейки 
ссылается не на nil (тогда бы это был правильный список),
а непосредственно на B. 

Т.е. в первом случае мы имеем

[ | ] -> B
 |
 V
 A

а во втором

[ | ] -> [ | ] -> nil
 |        |
 V        V
 A        B

stassats ★★★★
()
Ответ на: комментарий от stassats

По сути во втром случае у нас выходит (a b . nil), но просто . nil не печатается.

stassats ★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.