Yep, your research is pretty much the norm, I think. The only uses I’m aware of for
fn itself (plus some bootstrapping things in clojure.core before
fn is created)
:once metadata to avoid memory leaks
If you take a look at the implementation of
fn (https://github.com/clojure/clojure/blob/03cd9d159a2c49a21d464102bb6d6061488b4ea2/src/clj/clojure/core.clj#L4293-L4354), you’ll see that it adds a lot: destructuring, pre- and post-conditions, and some error handling bits.
I mostly learned about
fn* through reading the Clojure source code, but there’s also a helpful blog post by Christophe Grand with some more detail about the
:once bits (seems to be down right now, but: http://clj-me.cgrand.net/2013/09/11/macros-closures-and-unexpected-object-retention/)
^:once, there’s no reason I’m aware of for programmers to ever use
fn* directly: it’s strictly less useful aside from that.
Hope that helps!