liveBook · Manning

Type hints

As explained in Clojure: The Essential Reference

A type hint is metadata that annotates a Clojure expression or argument with Java type information to guide compilation, method dispatch, or interoperability.

A type hint supplies Java type information where Clojure’s compiler cannot infer it. Its practical use is to resolve Java method calls without reflection. Turn on `*warn-on-reflection*` to find calls that need attention; a value’s runtime type alone does not necessarily tell the compiler its type. section 2.1.1 section 21.7.6

Place a hint where the compiler needs the type:

  • Hint a function argument used as a Java method target, as in `(defn get-bytes [^String s] (.getBytes s (StandardCharsets/UTF_8)))`. A `^Mac` hint on the `mac` argument similarly resolves `.doFinal`. section 2.1.1
  • Hint the method name in `memfn`, as in `(memfn ^String toLowerCase)`. `memfn` propagates that metadata to the target object of the generated function. section 2.2.7
  • Hint a primitive array at the call site, as in `(aset ^ints a 0 9)`, or use the typed setter `(aset-int a 0 9)`. The setter is a convenient alternative when an array lookup has obscured its type. section 21.7.6

Find and remove a reflection warning

With reflection warnings enabled, calls to `.getBytes` on an unhinted `s` and `.doFinal` on an unhinted `mac` report unknown target classes. Adding `^String` and `^Mac` to those parameters removes the warnings. In the illustrated signing benchmark, the elapsed time falls from about 1054 ms to 449 ms for 100,000 requests; those figures are observations from that run, not a timing guarantee. section 2.1.1

(defn get-bytes [^String s]                   ; #1
  (.getBytes s (StandardCharsets/UTF_8)))

(defn compute-hmac [^Mac mac canonical]       ; #2
  (.doFinal mac (get-bytes canonical)))

(time (dotimes [i 100000]
  (sign-request (str "http://example.com/tx/" i))))

;; "Elapsed time: 449.417098 msecs"           ; #3

Shows both parameter hints and the timed signing call after the warnings are addressed. section 2.1.1

Hints are not a substitute for making an operation visible at the right point. An ordinary wrapper around an overloaded Java method can select the generic `Object` overload even when its caller converts arguments to `int`; an inlined wrapper lets that call-site type information reach Java method selection. Use hints or typed operations to resolve a specific interop problem, then check the resulting warnings and behavior. section 4.5 section 21.7.6

How Clojure: The Essential Reference covers it

How deep it goes
Works through hint placement, reflection warnings, benchmark results, and a typed-setter alternative; does not develop a general type system.
Examples
Uses a request-signing benchmark, a hinted `memfn` call, and `aset` versus `aset-int` on an integer array.
What it assumes
Assumes familiarity with Clojure function calls and basic Java interoperability; shows concrete hint syntax through examples.
What you can do after
Diagnose/debug Java interop reflection warnings and apply hints or typed setters where type information is missing.
How it connects
Connects function arguments, Java method calls, reflection, `memfn`, primitive arrays, and function inlining.

Also explained in

Compare how 17 books explain type hints →

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.