Примитив cons
просто связывает две вещи, факт, что некоторые из этих вещей считаются списками случайным. Например, это работает и создает пару (также известную как клетка конса):
(cons 1 2)
=> '(1 . 2) ; a pair
Теперь, если второй аргумент cons
случается список, то результат будет новым список, и первый аргумент cons
будет добавлен во главе старого списка. Другими словами: создать список вам нужен список, даже если он пуст:
(cons 1 '(2 3))
=> '(1 2 3) ; a list
(cons 1 (cons 2 '()))
=> '(1 2) ; a list
(cons 1 '())
=> '(1) ; a list
Но если второй аргумент cons
является не список, то результат будет просто пара, или неподходящий список, что означает, что она не заканчивается в '()
, как это следует рассматривать список:
(cons '(1 2) 3)
=> '((1 2) . 3) ; a pair, not a list
(cons 1 (cons 2 3))
=> '(1 2 . 3) ; an improper list
Просто чтобы прояснить, вы не можете использовать cons
для добавления элементов в конец списка. Обычный способ построения списка происходит справа налево, добавление элементов в обратном направлении в положении головы - говорят, что вы хотите построить список '(1 2 3)
, то вы должны cons
элементов в порядке 3 2 1
:
(cons 3 '()) ; list is '(3)
(cons 2 (cons 3 '())) ; list is '(2 3)
(cons 1 (cons 2 (cons 3 '()))) ; list is '(1 2 3)
в тех редких случаях, когда вам нужно добавить еще один элемент в конце (и поверьте мне, делать так, как правило, означает, что вы думаете, алгоритм неправильно), вы можете использовать append
, который получает два списка в качестве аргументов:
(append '(1 2 3) '(4))
=> '(1 2 3 4)
@ Ответ ÓscarLοpez expla это очень хорошо. Полезно понять, что в семействе языков Lisp не совсем правильно думать о 'cons' как о операции _list_. Языки Lisp обычно имеют _cons cells_ как подлинные типы данных, а затем реализуют списки как массивные типы данных. То, что мы называем списками, - это списки _by convention_. Я упомянул об этом в [более раннем ответе] (http://stackoverflow.com/a/19126410/1281433), в котором описывается, как мы можем часто скрывать ячейки в списках _implement_, но как мы можем также препятствовать ячейкам для реализации других структур, таких как деревья. –
@JoshuaTaylor Страница Не найдено. –
@hanQiu Я думаю, что вопрос был удален. Но теперь есть раздел в документации SO, который охватывает ту же идею: [списки как соглашение] (http://stackoverflow.com/documentation/common-lisp/2622/cons-cells-and-lists/8700/lists-as -a-конвенция # т = +201608091045099806348) –