Une différence est qu'elle conj
accepte n'importe quel nombre d'arguments à insérer dans une collection, alors qu'elle cons
n'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.Cons
ne met pas en œuvre clojure.lang.Counted
, donc a count
on 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 PersistentList
et ainsi Counted
).
L'intention derrière les noms est, je crois, cela cons
signifie de contre (truire une suite) 1 , alors que cela conj
signifie de conj (joindre un élément à une collection). Le seq
cours de construction par cons
commence avec l'élément passé en premier argument et a pour next
/ rest
partie la chose résultant de l'application de seq
la deuxième argument; comme affiché ci-dessus, le tout est de classe clojure.lang.Cons
. En revanche, conj
renvoie toujours une collection à peu près du même type que la collection qui lui est passée. (En gros, parce que a PersistentArrayMap
sera transformé en a PersistentHashMap
dès qu'il dépassera 9 entrées.)
1 Traditionnellement, dans le monde Lisp, cons
contre (truit une paire), Clojure s'écarte donc de la tradition Lisp en ayant sa cons
fonction construire un seq qui n'a pas de traditionnel cdr
. L'utilisation généralisée de cons
pour 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».