Ответ 1
Lisp обеспечивает структуру данных примитивных минусов и обозначение для нее.
В этой главе представлены:
- Символьные выражения, сделанные из атомов и пар символических выражений, написанных с использованием точечной нотации:
( a . b )
- обозначение списка для сокращения некоторых символических выражений
(a b c)
- атомный символ
nil
для завершения списков - примитивные функции
car
,cdr
,cons
,eq
иatom
- несколько других функций:
ff
,subst
,equal
,null
,cadr
,caddr
,null
,append
,among
,pair
,assoc
,sublis
,apply
,eval
,...
В начале Lisp добавлены функции мутаций cons-ячеек: rplaca
(означает замену автомобиля) и rplacd
(означает замену cdr). См. Руководство по программированию Lisp 1.5 от Джона МакКарти и др. с 1962 года. Эти функции позволяют нам писать деструктивные функции, а также позволяют создавать циклические структуры данных, такие как циклические списки.
Общий Lisp
Обычно диалекты Lisp реализуют большую часть этого. Общий Lisp не является исключением, и для этого эта функция описана в стандарте Common Lisp: Conses. Примеры с использованием упомянутых выше функций:
; pair two lists into a list of cons cells
; the function pair is called pairlis in Common Lisp
CL-USER 17 > (pairlis '(john mary eva) `(34 29 40))
((EVA . 40) (MARY . 29) (JOHN . 34))
; find a cons cell in a list of cons cells, based on the content of the car of those cons cells
CL-USER 18 > (assoc 'eva
(pairlis '(john mary eva)
`(34 29 40)))
(EVA . 40)
; create a tree out of cons cells and atoms
CL-USER 19 > (cons (cons 10 20) (cons 30 40))
((10 . 20) 30 . 40)
; a cons cell is not an atom
CL-USER 20 > (atom (cons 1 2))
NIL
; a cons cell is not nil
CL-USER 21 > (null (cons 1 2))
NIL
; substitute an item with a new one in a tree
CL-USER 22 > (subst 30 ; new
'bar ; old
'((10 . 20) . (bar . 40))) ; tree
((10 . 20) 30 . 40) ; also written as ((10 . 20) . (30 . 40))
; substitute several items in a tree, using an assoc list
; to describe the substitutions
CL-USER 23 > (sublis '((a . 10) (d . 40)) ; substitutions
'((a . b) . (c . d))) ; tree
((10 . B) C . 40)
Списки - это особый случай символических выражений. Они обычно пишутся без точек:
CL-USER 24 > '(a . (b . nil))
(A B)
Общий Lisp также поддерживает мутирующие операции rplaca
и rplacd
of Lisp 1.5:
CL-USER 25 > (let ((c (cons 0 1))) ; create a cons
(print c) ; print it
(print (rplaca c 'foo)) ; replace the car
(print (rplacd c 'bar)) ; replace the cdr
(print (eq c (rplaca c 'baz))) ; identical ?
(values))
(0 . 1) ; the cons cell
(FOO . 1) ; car replaced
(FOO . BAR) ; cdr replaced
T ; still the same object
Emacs Lisp
Emacs Lisp также реализует вышеуказанные функции:
ELISP> (sublis '((a . 10) (d . 40))
'((a . b) . (c . d)))
((10 . b) c . 40)
Clojure
Clojure не поддерживает эти символические выражения, описанные Джоном МакКарти. Он не имеет ячеек cons, нет точечной нотации и не обеспечивает вышеуказанный интерфейс. Например, атом означает что-то совершенно другое в Clojure. cons
не создает ячейку cons. Списки не состоят из cons-ячеек.
В Clojure точка - это еще один символ:
user=> (count '(1 . 2))
3
Существует примитивная функция для построения списков:
user=> (list 1 2 3)
(1 2 3)
В результате должен быть список:
user=> (list? (list 1 2 3))
true
Существует функция, называемая cons
:
user=> (cons 0 (list 1 2 3))
(0 1 2 3)
Как-то это не список:
user=> (list? (cons 0 (list 1 2 3)))
false
В основном Clojure использует разные структуры данных (- > sequences, логические списки) со своим собственным именованием и семантикой. Даже если имена похожи на имена Lisp, не ожидайте, что они сделают то же самое.
Схема
В языке программирования также предусмотрены аналогичные элементы cons. В нем отсутствуют некоторые функции, но их можно легко реализовать. Например, sublis
может быть реализован как в схеме (см. initdr.scm):
(define (sublis alist tree)
(if (pair? tree)
(cons (sublis alist (car tree))
(sublis alist (cdr tree)))
(if (assv tree alist)
(cdr (assv tree alist))
tree)))