Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

purpose of defn in Clojure

Tags:

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.

like image 791
planarian Avatar asked Mar 24 '23 01:03

planarian


2 Answers

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.

like image 148
sloth Avatar answered Apr 01 '23 21:04

sloth


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.

like image 28
Jeremy Avatar answered Apr 01 '23 20:04

Jeremy