Một điểm khác biệt là conj
chấp nhận bất kỳ số lượng đối số nào để chèn vào một bộ sưu tập, trong khi cons
chỉ lấy một:
(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
Một sự khác biệt khác là trong lớp của giá trị trả về:
(class (conj '(1 2 3) 4))
; => clojure.lang.PersistentList
(class (cons 4 '(1 2 3))
; => clojure.lang.Cons
Lưu ý rằng chúng không thực sự thay thế được cho nhau; đặc biệt, clojure.lang.Cons
không triển khai clojure.lang.Counted
, vì vậy a count
trên nó không còn là một hoạt động thời gian cố định (trong trường hợp này, nó có thể giảm xuống 1 + 3 - 1 xuất phát từ chuyển tuyến tính qua phần tử đầu tiên, 3 đến từ (next (cons 4 '(1 2 3))
là a PersistentList
và do đó Counted
).
Ý định đằng sau những cái tên, tôi tin rằng, cons
có nghĩa là khuyết điểm (truct a seq) 1 , trong khi conj
có nghĩa là liên kết (sắp xếp một mục vào một bộ sưu tập). Việc seq
được xây dựng bởi cons
bắt đầu với phần tử được truyền làm đối số đầu tiên của nó và có phần tử next
/ rest
phần của nó là kết quả của việc áp dụng seq
đối số thứ hai; như được hiển thị ở trên, toàn bộ điều là của lớp clojure.lang.Cons
. Ngược lại, conj
luôn trả về một tập hợp có cùng kiểu với tập hợp được chuyển đến nó. (Đại khái là vì a PersistentArrayMap
sẽ được chuyển thành a PersistentHashMap
ngay khi nó phát triển vượt quá 9 mục nhập.)
1 Theo truyền thống, trong thế giới Lisp, cons
khuyết điểm (tructs một cặp), vì vậy Clojure khác với truyền thống Lisp trong việc cons
hàm của nó tạo ra một seq không có truyền thống cdr
. Việc sử dụng khái quát cons
nghĩa là "xây dựng một bản ghi của một số kiểu này hoặc kiểu khác để giữ một số giá trị cùng nhau" hiện đang phổ biến trong việc nghiên cứu các ngôn ngữ lập trình và triển khai chúng; đó là những gì có nghĩa là khi "tránh lợi dụng" được đề cập.