Отличие заключается в том, что conj
принимает любое количество аргументов для вставки в коллекцию, в то время как cons
занимает всего один:
(conj '(1 2 3) 4 5 6)
; => (6 5 4 1 2 3)
(cons 4 5 6 '(1 2 3))
; => IllegalArgumentException due to wrong arity
Другим отличием является то в классе возвращаемого значения:
(class (conj '(1 2 3) 4))
; => clojure.lang.PersistentList
(class (cons 4 '(1 2 3))
; => clojure.lang.Cons
Обратите внимание, что они не являются взаимозаменяемыми; в частности, clojure.lang.Cons
не реализует clojure.lang.Counted
, поэтому count
на нем больше не является операцией с постоянным временем (в этом случае он, вероятно, уменьшится до 1 + 3 - 1 исходит из линейного обхода по первому элементу, 3 получается из (next (cons 4 '(1 2 3))
является PersistentList
и таким образом Counted
).
Намерения за именами, я считаю, что cons
означает минусы (truct в следующем) , в то время как conj
означает CONJ (ойн элемента на коллекцию). Строка seq
, созданная cons
, начинается с элемента, переданного в качестве первого аргумента, и имеет в качестве своей next
/rest
часть, полученную в результате применения seq
ко второму аргументу; как показано выше, все дело в классе clojure.lang.Cons
. Напротив, conj
всегда возвращает коллекцию примерно того же типа, что и переданная ей коллекция. (Грубо говоря, потому что PersistentArrayMap
будет превращен в PersistentHashMap
как только он вырастает за 9 записей.)
Традиционно в Лиспе, cons
минусов (tructs пары), так что Clojure уходит из традиции Лиспа в том, что ее функция cons
построила seq, который не имеет традиционного cdr
. Обобщенное использование cons
означает «построить запись того или иного типа для хранения целого ряда значений», в настоящее время является вездесущим при изучении языков программирования и их реализации; это то, что имеется в виду, когда упоминается «избегать consing».
Какая фантастическая запись! Я не знал, что существует тип «Минус». Отлично сработано! –
Спасибо. Рад слышать это. :-) –
Кстати, в качестве специального случая '(cons foo nil)' возвращает одноэлемент 'PersistentList' (а также для' conj'). –