Una diferencia es que conj
acepta cualquier número de argumentos para insertar en una colección, mientras que cons
solo toma 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
Otra diferencia está en la clase del valor de retorno:
(class (conj '(1 2 3) 4))
; => clojure.lang.PersistentList
(class (cons 4 '(1 2 3))
; => clojure.lang.Cons
Tenga en cuenta que estos no son realmente intercambiables; en particular, clojure.lang.Cons
no implementa clojure.lang.Counted
, por lo que un count
sobre que ya no es una operación de tiempo constante (en este caso probablemente reduciría a 1 + 3 - 1 al proviene de recorrido lineal en el primer elemento, el 3 viene de (next (cons 4 '(1 2 3))
ser PersistentList
y así Counted
).
La intención detrás de los nombres es, creo, que cons
significa construir una seq. 1 , mientras que conj
significa conjugar un elemento en una colección. El seq
ser construido por cons
comienza con el elemento pasado como primer argumento y tiene como su next
/ rest
parte lo resultante de la aplicación de seq
al segundo argumento; como se muestra arriba, todo es de clase clojure.lang.Cons
. Por el contrario, conj
siempre devuelve una colección de aproximadamente el mismo tipo que la colección que se le pasó. (Aproximadamente, porque a PersistentArrayMap
se convertirá en a PersistentHashMap
tan pronto como supere las 9 entradas).
1 Tradicionalmente, en el mundo Lisp, cons
contras (construye un par), por lo que Clojure se aparta de la tradición Lisp al hacer que su cons
función construya un seq que no tiene un tradicional cdr
. El uso generalizado de cons
para significar "construir un registro de un tipo u otro para mantener juntos un número de valores" es actualmente omnipresente en el estudio de los lenguajes de programación y su implementación; eso es lo que se quiere decir cuando se menciona "evitar la consulta".