Une différence est que le conj
accepte un nombre quelconque d'arguments à insérer dans une collection, tout cons
prend une:
(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 est 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 qu'elles ne sont pas interchangeables; en particulier, clojure.lang.Cons
ne met pas en oeuvre clojure.lang.Counted
, donc un count
, il n'est plus une constante de temps de l'opération (dans ce cas, il serait probablement réduire à 1 + 3 -- le 1 vient de linéaire de la traversée sur le premier élément, le 3 vient d' (next (cons 4 '(1 2 3))
être PersistentList
et ainsi, Counted
).
L'intention derrière le nom est, je crois, que cons
moyen de cons(truct seq)1, alors que conj
signifie conj(oin d'un élément sur une collection). L' seq
construit par cons
commence avec l'élément passé en premier argument et a next
/ rest
de la partie de la chose résultant de l'application de l' seq
pour le deuxième argument; comme affiché ci-dessus, le tout est de classe clojure.lang.Cons
. En revanche, conj
toujours retourne une collection d'à peu près du même type que la collection passée. (En gros, parce qu'un PersistentArrayMap
sera transformée en PersistentHashMap
dès qu'il pousse au-delà de 9 entrées.)
1 Traditionnellement, dans le Lisp monde, cons
contre(tructs une paire), donc Clojure s'écarte de la Lisp tradition en ayant son cons
de la fonction construire un seq qui n'ont pas de traditionnels cdr
. L'utilisation généralisée de l' cons
signifie "construire un record de quelque type ou un autre d'organiser un certain nombre de valeurs" est actuellement omniprésente dans l'étude des langages de programmation et leur mise en œuvre; c'est ce que voulait dire quand ", en évitant consing" est mentionné.