I'm a little puzzled about the role of defn. If fn only produced anonymous functions, I could understand the need for a construct that combines the functionality of def and fn, but fn can also create named functions. At least in the repl, I don't see how that usage differs from defn.
When you provide a name symbol to fn
, it's only bound within the function definition to the function object itself. This is to allow anonymous functions to call themselves (Clojure - special forms).
So to create a function with fn
bound to a global accessible name, you have to use
(def somename
(fn ...body...
and defn
is just a shortcut for this.
(defn somename
...body...
In response to your comment, from a fresh repl:
Give me some Clojure:
> (fn foo [] (+ 1 3))
#<sandbox31764$eval31779$foo__31780 sandbox31764$eval31779$foo__31780@12eae8eb>
> (foo)
java.lang.RuntimeException: Unable to resolve symbol: foo in this context
> (defn foo [] (+ 1 3))
#'sandbox31764/foo
> (foo)
4
>
As you can see, I can't call the foo
function created with fn
, because it's not bound to a Var.
The main difference is that defn
creates a global name, wheres fn
only creates a lexical one. The global name is also a var, since it's ultimately created with def
. The name you can give to an anonymous function is not a var and is only within scope of that function. This is mostly so the function can be recursive.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With