liveBook · Manning

Comparable interface

As explained in Clojure: The Essential Reference

The Java Comparable interface defines a natural ordering for instances of a class through its compareTo method.

Java’s `Comparable` interface gives instances a natural ordering through `compareTo`. Clojure’s `compare` uses that ordering for compatible values, and functions such as `sort` and `sort-by` use `compare` by default. A comparison returns a negative number, zero, or a positive number—not necessarily −1, 0, or 1. section 6.4

The ordering must be usable for the values being compared:

  • `compareTo` on the first value must accept the second value’s type; implementing `Comparable` alone does not make every pair compatible. An incompatible pair can cause a `ClassCastException`. section 6.4
  • `compare` also handles `nil` and pairs of numbers. Clojure vectors, keywords, ratios, refs, and symbols provide their own comparison behavior. section 6.4

Make records sortable

A `Point` record can implement `Comparable` with `compareTo` that calls `compare` on each point’s distance from an origin. A `GasStation` record can then compare its locations; `(sort gas-stations)` orders stations by distance rather than brand. The same ordering can govern keys in a `sorted-map`. Use `sorted-map-by` when a different comparator is needed. section 6.4 section 11.1.3

(defn- sq [x] (* x x))

(defn- distance [x1 y1 x2 y2]                    ; #1
  (Math/sqrt (+ (sq (- x1 x2)) (sq (- y1 y2)))))

(defrecord Point [x y distance-origin]           ; #2
  Comparable
  (compareTo [this other]
    (compare (distance-origin (:x this) (:y this)) ; #3
             (distance-origin (:x other) (:y other)))))

(defn relative-point [x1 y1 x2 y2]          ; #4
  (->Point x1 y1 (partial distance x2 y2)))

(defrecord GasStation [brand location]      ; #5
  Comparable
  (compareTo [this other]
    (compare (:location this) (:location other)))) ; #6

The record definitions show `compareTo` delegating to `compare`, so each record’s ordering follows the value chosen for comparison. section 6.4

How Clojure: The Essential Reference covers it

How deep it goes
Explains comparison results, compatibility requirements, exceptions, and a worked record implementation without detailing Java interface internals.
Examples
Uses distance-ordered point and gas-station records, plus sorted-map keys, to demonstrate ordering.
What it assumes
Assumes familiarity with Clojure records and Java types; defines the comparison result and identifies the required `compareTo` method.
What you can do after
Build it from scratch by implementing `compareTo` on a Clojure record so its instances can be sorted.
How it connects
Connects `compareTo` with `compare`, `sort`, `sort-by`, `sorted-map`, and custom comparators.

Also explained in

Compare how 3 books explain Comparable interface →

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.