Une différence est qu'elle conjaccepte n'importe quel nombre d'arguments à insérer dans une collection, alors qu'elle consn'en prend qu'un:
(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
Une autre différence réside dans la classe de la valeur de retour:
(class (conj '(1 2 3) 4))
; => clojure.lang.PersistentList
(class (cons 4 '(1 2 3))
; => clojure.lang.Cons
Notez que ceux-ci ne sont pas vraiment interchangeables; en particulier, clojure.lang.Consne met pas en œuvre clojure.lang.Counted, donc a counton ce n'est plus une opération à temps constant (dans ce cas il se réduirait probablement à 1 + 3 - le 1 provient d'un parcours linéaire sur le premier élément, le 3 vient d' (next (cons 4 '(1 2 3))être a PersistentListet ainsi Counted).
L'intention derrière les noms est, je crois, cela conssignifie de contre (truire une suite) 1 , alors que cela conjsignifie de conj (joindre un élément à une collection). Le seqcours de construction par conscommence avec l'élément passé en premier argument et a pour next/ restpartie la chose résultant de l'application de seqla deuxième argument; comme affiché ci-dessus, le tout est de classe clojure.lang.Cons. En revanche, conjrenvoie toujours une collection à peu près du même type que la collection qui lui est passée. (En gros, parce que a PersistentArrayMapsera transformé en a PersistentHashMapdès qu'il dépassera 9 entrées.)
1 Traditionnellement, dans le monde Lisp, conscontre (truit une paire), Clojure s'écarte donc de la tradition Lisp en ayant sa consfonction construire un seq qui n'a pas de traditionnel cdr. L'utilisation généralisée de conspour signifier "construire un enregistrement d'un type ou d'un autre pour contenir un certain nombre de valeurs ensemble" est actuellement omniprésente dans l'étude des langages de programmation et de leur implémentation; c'est ce que signifie «éviter de consommer».