You want to create a set data structure either as a literal, or from an existing data structure.
The literal syntax for a set is a hash symbol preceding the set contents wrapped in curly braces.
#{:a :b :c}
;; -> #{:a :b :c}
To create a set from an existing collection, you can use the set function to transform it directly.
(set [:a :b :c :a])
;; -> #{:a :b :c}
Alternatively, you could use the into function, which repeatedly applies conj to items from a sequence on to an empty set, constructing a set containing all the items from the sequence.
(into #{} [:a :b :c :a])
;; -> #{:a :b :c}
Oddly enough, as with vectors, the into technique is considerably faster than the direct set constructor. Use it whenever you’re working with large sets where performance is a concern.
These techniques all construct hash sets; sets which use a hashtable as their internal representation.
Clojure also supports sorted sets, which maintain their internal structure as a sorted binary tree. The only way to create a sorted set is via the sorted-set function, which creates a new instance of clojure.lang.PersistentTreeSet (the concrete type of for a sorted set) containing any arguments you pass.
Adding items to a sorted set with conj will yield another sorted set, so to obtain a sorted set with items in it, just conj (or use into) to add the items you need.
To inspect a set to see whether it’s a hash set or a sorted set, you can either look at the concrete type in the REPL using the class function, or use the sorted? predicate, which returns true only for inherently sorted collections.
(def my-unsorted (into #{:a :b} [:b :c]))
(def my-sorted (into (sorted-set :a :b) [:b :c]))
(sorted? my-unsorted)
;; -> false
(sorted? my-sorted)
;; -> true
(class my-sorted)
;; -> clojure.lang.PersistentTreeSet
If the values you want to sort don’t have a natural sort order (or you don’t want to use their natural ordering), you can create a sorted set with a custom comparator function using sorted-set-by. sorted-set-by takes a comparator function as its first argument, and uses the rest of the arguments as values in the set just as sorted-set does.
Comparator functions are a predicate function that must take two arguments, and should return true if the arguments are in sorted order (that is, if the first argument should before the second argument in the desired sort order). Conveniently, this includes built-in functions such as <.
So, to create a sorted set that sorts items in descending order, just pass the > function to sorted-set-by.
(sorted-set-by > 3 1 5)
;; -> #{5 3 1}
(sorted-set-by < 3 1 5)
;; -> #{1 3 5}
In addition to the quality of being sorted or not, there are some performance tradeoffs to consider when choosing between sorted and hash sets. Hash sets are based on hashtables, which offer constant time insert and lookup in most cases. However, they do require some degree of memory overhead. Sorted sets, based on a balanced red-black binary tree, are more memory efficient but not quite as fast at lookup and insertion.