purpose of defn in Clojure
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.
下一篇: 在Clojure中定义的目的