Based on command-line input, I need to set some run-time constants which a number of downstream functions are going to use. The code in those functions may execute in other threads so I am not considering the "declare var and use binding macro" combination. What are the pros/cons of using a var (with alter-var-root) for this versus using an atom? That is,
(declare *dry-run*) ; one of my constants
(defn -main [& args]
; fetch command line option
;(cli args ...)
(alter-var-root #'*dry-run* (constantly ...))
(do-stuff-in-thread-pool))
versus
(def *dry-run* (atom true))
(defn -main [& args]
; fetch command line option
;(cli args ...)
(reset! *dry-run* ...)
(do-stuff-in-thread-pool))
If there is another option besides these two which I should consider, would love to know.
Also, ideally I would've preferred not to provide an initial val to the atom because I want to set defaults elsewhere (with the cli invocation), but I can live with it, especially if using the atom offers advantages compared to the alternative(s).
Write-once values are exactly the use case promises are designed for:
(def dry-run (promise))
(defn -main []
(deliver dry-run true))
(defn whatever [f]
(if @dry-run
...))
AFAIK alter-var-root
only guarantees synchronized variable value changing and doesn't guarantee safe reading during this change. On other hand the atom
really provides atomically change the state of identity.
If you don't want provide an initial value you can just set it to nil
:
(def *dry-run* (atom nil))
What is wrong with just using a var and alter-var-root
? You set up the new value in your startup function, before you really kick-off the workers. So there is no race in reading. And you can save the @
everywhere you need the value.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With