liveBook · Manning

Comparison function

As explained in Clojure: The Essential Reference

The Java Comparator interface defines an object contract for comparing two values through a compare method.

A comparison function decides the relative order of two values. Its numeric result is negative when the first value comes before the second, zero when they compare equally, and positive when it comes after. Test the sign, not an exact value: (compare "a" "z") returns -25, not -1. section 6.4

Clojure's compare is the default comparison function for sorting and ordered collections. It accepts two arguments and can compare numbers, nil, and compatible values implementing java.lang.Comparable. A custom comparison function supplies a different order; Clojure functions can also serve as java.util.Comparator objects for sorted-set-by. section 6.4 section 13.3

Reverse a sorted set

(sorted-set-by #(compare %2 %1) "t" "d" "j") ;; #{"t" "j" "d"} Reversing the arguments reverses the order. sorted-map-by likewise accepts a comparison function for its keys; without one, sorted-map and sorted-set use the default order. section 11.1.3 section 13.3

In a sorted map or set, zero has a consequence beyond ordering: the collection treats the compared keys or elements as the same. Comparing vectors only by count therefore collapses different vectors of equal length. Add a tie-breaker if both must remain present. section 11.1.3 section 13.3

Keep equal-length vectors distinct

(def by-count (fn [a b] (compare [(count b) a] [(count a) b]))) (sorted-set-by by-count [1 :a] [:b] [3 :c] [:v]) ;; #{[1 :a] [3 :c] [:b] [:v]} Length determines the primary order; the vectors themselves break ties. section 13.3

Check edge cases before relying on an order. Incompatible values can cause ClassCastException. compare treats comparisons involving Double/NaN as zero, which can make sorting results surprising. The practical rule is to choose a comparison that both orders the values and distinguishes every value the collection must retain. section 6.4 section 13.3

How Clojure: The Essential Reference covers it

How deep it goes
Defines the three-way result, works through custom ordering and tie-breakers, and identifies incompatible inputs and NaN behavior.
Examples
Uses reversed string ordering, equal-length vector collisions, and vector tie-breakers to demonstrate comparator behavior.
What it assumes
Assumes basic Clojure functions and collections while defining comparison results and introducing their Java interface connections.
What you can do after
Apply it via sorted-map-by and sorted-set-by to choose an order without unintentionally collapsing distinct keys or elements.
How it connects
Connects comparison functions to java.lang.Comparable, java.util.Comparator, sorting, sorted maps, and sorted sets.

Also explained in

Compare how 3 books explain comparison function →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Clojure: The Essential Reference. The section links point to the parts of the book it draws on.