What is the difference between set and hash-set in Clojure?

Viewed 448

I can't find an explanation on the documentation nor on the web for why there are two different functions that seem to do practically the same thing, apart from accepting one a collection and the other one a list of arguments (but this could be easily solved using (apply hash-set coll)).

3 Answers

Just checked the source code for set and hash-set. You are right that there is practically no difference, aside from one accepting multiple arguments and the other accepting a collection.

Here is the source, by the way:

For set

For hash-set

It is just for convenience. Same with vector vs vec. However it is not completely parallel for maps and lists:

(vector 0 1 2)            => [0 1 2]
(apply vector (range 3))  => [0 1 2]
(vec (range 3))           => [0 1 2]

(hash-set 0 1 2)            => #{0 1 2}
(apply hash-set (range 3))  => #{0 1 2}
(set (range 3))             => #{0 1 2}

(hash-map :a 1 :b 2)          => {:b 2, :a 1}
(apply hash-map [:a 1 :b 2])  => {:b 2, :a 1}
(into {} [[:a 1] [:b 2]])     => {:a 1, :b 2}

(list 0 1 2)            => (0 1 2)
(apply list (range 3))  => (0 1 2)
(into (list) (range 3)) => (2 1 0)  ; *** reversed order ***

Since we can define each in terms of the other:

(defn hash-set [& args]
  (clojure.core/set args))

or

(defn set [coll]
  (apply clojure.core/hash-set coll))

... it is likely that both are defined separately for speed.

Related