Re-def vars in Clojure (script)

I am trying to find an idiomatic way to defer var initialization (which I really intend to be immutable).

(def foo nil) ... (defn init [] ; (def foo (some-function)) ; (set! foo (some-function))) 

I know that Rich Hickey said re-election is not idiomatic . Does set! match set! here?

+6
source share
2 answers

I would use delay :

It receives the body of expressions and gives a Delay object, which will only call the body the first time it is forced (with a force or tree / @), and will cache the result and return it to all subsequent force calls. See Also - implemented?

Usage example:

 (def foo (delay (init-foo))) ;; init-foo is not called until foo is deref'ed (defn do-something [] (let [f @foo] ;; init-foo is called the first time this line is executed, ;; and the result saved and re-used for each subsequent call. ... )) 
+5
source

Besides using delay, as Alex says in his answer, install! works just fine because vars are just javascript variables under the hood.

Yous should not be installed directly! such as such, but for special cases like this, I personally allow myself (economically) to do this (i.e. the data is actually normal immutable Clojure after installation). One example when I do this is to override functions in debug builds:

 (defn foo [] release code here) 

Then to a file that is added only to debug builds:

 (defn debug-foo [] (.log js/console "foo called")) (set! foo debug-foo) 
+1
source

All Articles