(defn ^Bar foo ...)
tells that function foo returns something of class Bar.
(f ^Bar expr) says that expr is of type Bar.
(let [ ^Bar e expr] ... says that e is of type Bar.
(Bar can be a class or an interface.)
The main usage (at least for me) is avoiding reflection in the context
of direct call to a Java method.
if you write:
(defn foo [x]
(.clone x))
For Clojure, x is an object and so it does not know anything about its
interface (the methods it understands). So it cannot do better than a
"dynamic dispatch", looking at x class by reflection and searching for
a method named clone with the right signature.
It can be long, and so should be avoided on code that is called more
than rarely.
To avoid that:
(defn foo [^Clonable x]
(.clone x))
Now, Clojure knows at compile-time that x is Clonable.
It can check that clone is in the known interface and use a direct
method call, which is faster.
(set! *warn-on-reflection* true)
makes the compiler emit a warning in the first case.
You should remark that this kind of problem only occurs when
interfacing directly with the host language.
Other usages may happen, like when a specific signatures is needed for
interoperability.
Hope I am not too wrong and that helps.
Nicolas