Can I redefine function in real-time without side effects? Is defn thread-safe?
Yes, it's thread safe.... but it does have side effects. Hence you may get unexpected results depending on what you are trying to do.
In essence, defn on an existing function will rebind the corresponding var in the namespace.
This means that:
As long as you understand and are comfortable with that - you should be OK.
EDIT: In response to Arthur's comment, here's an example:
; original function
(defn my-func [x] (+ x 3))
; a vector that holds a copy of the original function
(def my-func-vector [my-func])
; testing it works
(my-func 2)
=> 5
((my-func-vector 0) 2)
=> 5
; now redefine the function
(defn my-func [x] (+ x 10))
; direct call to my-func uses the new version, but the vector still contains the old version....
(my-func 2)
=> 12
((my-func-vector 0) 2)
=> 5