Disclaimer: I'm a long way from a Clojure compiler expert, so take the following with an appropriate quantity of salt.
fn*
is an intrinsic version of fn
. Much of Clojure is implemented in Clojure, but some of the low-level functions are implemented in Java; fn*
is one such.
fn
is implemented in terms of fn*
. The source is here:
https://github.com/clojure/clojure/blob/master/src/clj/clojure/core.clj#L42
fn*
is implemented in the compiler:
https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Compiler.java#L47
There are actually two different versions of fn*
, referred to in the Java by the symbols FN
and FNONCE
. The first is a "bare" fn*
and the second is fn*
with the metadata ^{:once true}
, which is the version used by lazy-seq
.
^{:once true}
is used to let the compiler know that the closure containing the function will only be invoked once, and that it can perform closed-over local clearing. See this mailing list thread for more details.