Var vs atom for runtime constants

Based on the input on the command line, I need to set some runtime constants that will use some downstream functions. The code in these functions can be executed in other threads, so I do not consider the combination of "declare var and use a binding macro." What are the pros and cons of using var (with alter-var-root) for this or using an atom? I.e

(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)) 

against

 (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, in addition to these two, which I should consider, I would like to know.

In addition, ideally, I would prefer not to provide an initial val for the atom, because I want to set the default values โ€‹โ€‹elsewhere (with cli), but I can live with it, especially if using the atom gives an advantage over the alternative ( s).

+8
clojure
source share
3 answers

The values โ€‹โ€‹of "Write-once" are exactly used to use promises intended for:

 (def dry-run (promise)) (defn -main [] (deliver dry-run true)) (defn whatever [f] (if @dry-run ...)) 
+6
source share

AFAIK alter-var-root guarantees only a synchronized change in the value of a variable and does not guarantee a safe read during this change. On the other hand, atom does provide an atomic change in identity state.

If you do not want to provide an initial value, you can simply set it to nil :

 (def *dry-run* (atom nil)) 
+3
source share

What is wrong with using var and alter-var-root ? You set a new value in your start function before you start work. So there is no race in reading. And you can save @ wherever you need value.

+2
source share

All Articles