Una differenza è che conjaccetta un numero qualsiasi di argomenti da inserire in una raccolta, mentre ne consrichiede solo uno:
(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
Un'altra differenza è nella classe del valore restituito:
(class (conj '(1 2 3) 4))
; => clojure.lang.PersistentList
(class (cons 4 '(1 2 3))
; => clojure.lang.Cons
Nota che questi non sono realmente intercambiabili; in particolare, clojure.lang.Consnon implementa clojure.lang.Counted, quindi a countsu non è più un'operazione a tempo costante (in questo caso si ridurrebbe probabilmente a 1 + 3 - l'1 deriva dall'attraversamento lineare sul primo elemento, il 3 deriva (next (cons 4 '(1 2 3))dall'essere a PersistentListe quindi Counted).
L'intenzione dietro i nomi è, credo, che conssignifichi costruire un seq 1 , mentre conjsignifica congiungere un oggetto a una collezione. Il seqessendo costruito da consinizia con l'elemento passato come primo argomento e ha come next/ restparte la cosa risultante dall'applicazione seqal secondo argomento; come mostrato sopra, l'intera cosa è di classe clojure.lang.Cons. Al contrario, conjrestituisce sempre una raccolta approssimativamente dello stesso tipo della raccolta passata. (Approssimativamente, perché a PersistentArrayMapsarà trasformato in a PersistentHashMapnon appena supera le 9 voci.)
1 Tradizionalmente, nel mondo Lisp, conscostituisce una coppia, quindi Clojure si discosta dalla tradizione Lisp avendo la sua consfunzione di costruire un seq che non ha un tradizionale cdr. L'uso generalizzato di consper significare "costruire un record di un tipo o di un altro per tenere insieme un certo numero di valori" è attualmente onnipresente nello studio dei linguaggi di programmazione e della loro implementazione; questo è ciò che si intende quando si parla di "evitare il consumo".