4 Answers
4

defs are evaluated only once whereas defns (with or without arguments) are evaluated (executed) every time they are called. So if your functions always return the same value, you can change them to defs but not otherwise.

Ah, I did not know this, you saved me from some serious bugs! So if there is a def which accesses a reference it will never be recalculated? What about if the file is reloaded?
–
ZubairDec 16 '10 at 17:29

def is reevaluated when the file is reloaded.
–
Abhinav SarkarDec 16 '10 at 17:58

1

It seems wrong to me to say that defn forms are reevaluated. As pointed out in other answers, defn resolves to def at macro expanding time, and they indeed are all evaluated only once at file load time.
–
skuroOct 12 '11 at 9:13

@MattFenwick skuro's point is that defns are evaluated only once, just like every def - in this case, it defines a function. However, the body of the function defined may be evaluated any number of times. I don't think it's a useful distinction, but he's not saying anything false.
–
amalloyDec 12 '11 at 2:06

The def special form creates a Var object identified by a symbol given as its first argument. Identification is created by associating the given symbol with a Var in a map called namespace.

The Var holds a reference to some value, which could be expressed (among others):

as a constant form, which always evaluates to its own value:
(def x 1)
x
; => 1 ; x holds a reference to a number 1

as a function form, which at first is evaluated to its resulting value:
(def x (+ 2 2))
x
; => 4 ; x holds a reference to a number 4

as a Java method form, which at first is evaluated to its resulting value:
(def x (System/currentTimeMillis))
x
; => 1417811438904
; x holds a reference to a number 1417811438904
x
; => 1417811438904
; still the same number!

There is a simple rule for all of the above. In case of def special form an S-expression given as its second argument is recursively evaluatedbefore binding is created, so the resulting Var is bound to the result of this evaluation.

Even fn is evaluated before, but its resulting value is a function object that holds a code. This code will be executed (and evaluated) each time the function is called. That's why there are different results.

The defn macro is just like def but internally it creates an anonymous function and then binds a Var object to it. Its second argument becomes a body of this function and it's not evaluated in a "regular" way. One could also say it is evaluated but as a lambda form – the result of the evaluation is a function object, not the result of some instant calculation.