Одна з різниць полягає в тому, що приймається 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означає "протистояти послідовності" 1 , тоді як conjозначає конфігувати (в предметі до колекції). Будова, seqщо будується шляхом, consпочинається з елемента, переданого як його перший аргумент, і є його next/ restчастиною річ, що виникає в результаті застосування seqдо другого аргументу; як показано вище, вся справа в класі clojure.lang.Cons. На відміну від цього, conjзавжди повертає колекцію приблизно того ж типу, що і колекція, передана їй. (Приблизно тому, що засіб PersistentArrayMapбуде перетворено на показник, PersistentHashMapяк тільки він перевищить 9 записів.)
1 Традиційно у світі Лісп consпроти, (довіряє пару), тому Clojure відходить від традиції Lisp, будучи consфункцією побудови послідовності, яка не має традиційного cdr. Узагальнене використання значень cons«побудова запису якогось типу або іншого для утримання кількох значень разом» наразі є повсюдним у вивченні мов програмування та їх реалізації; ось що мається на увазі, коли йдеться про "уникнення збитків".