Satu perbedaan adalah yang conj
menerima sejumlah argumen untuk dimasukkan ke dalam koleksi, sementara cons
hanya membutuhkan satu:
(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
Perbedaan lainnya adalah di kelas nilai yang dikembalikan:
(class (conj '(1 2 3) 4))
; => clojure.lang.PersistentList
(class (cons 4 '(1 2 3))
; => clojure.lang.Cons
Perhatikan bahwa ini tidak benar-benar dapat dipertukarkan; secara khusus, clojure.lang.Cons
tidak diimplementasikan clojure.lang.Counted
, jadi a count
on itu bukan lagi operasi waktu konstan (dalam hal ini mungkin akan berkurang menjadi 1 + 3 - 1 berasal dari traversal linier atas elemen pertama, 3 berasal dari (next (cons 4 '(1 2 3))
menjadi a PersistentList
dan demikian Counted
).
Maksud di balik nama-nama itu, saya percaya, itu cons
berarti kontra (truct a seq) 1 , sedangkan conj
berarti menyambungkan (oin item ke koleksi). The seq
sedang dibangun oleh cons
dimulai dengan elemen lulus sebagai argumen pertama dan memiliki sebagai yang next
/ rest
bagian hal yang dihasilkan dari penerapan seq
untuk argumen kedua; seperti yang ditunjukkan di atas, semuanya berkelas clojure.lang.Cons
. Sebaliknya, conj
selalu mengembalikan koleksi dengan jenis yang kira-kira sama dengan koleksi yang diteruskan kepadanya. (Secara kasar, karena a PersistentArrayMap
akan diubah menjadi PersistentHashMap
segera setelah berkembang melampaui 9 entri.)
1 Secara tradisional, dalam dunia Lisp, cons
kontra (membelah sepasang), maka Clojure berangkat dari tradisi Lisp dalam menjalankan cons
fungsinya membangun sekuens yang tidak bersifat tradisional cdr
. Penggunaan umum cons
untuk mengartikan "membuat catatan dari beberapa jenis atau lainnya untuk menyimpan sejumlah nilai bersama" saat ini ada di mana-mana dalam studi bahasa pemrograman dan implementasinya; itulah yang dimaksud ketika "menghindari kontra" disebutkan.