Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

var versus atom for runtime constants

Tags:

clojure

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

like image 475
Don Avatar asked Jan 14 '13 04:01

Don


3 Answers

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
    ...))
like image 89
amalloy Avatar answered Nov 06 '22 07:11

amalloy


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)) 
like image 22
mobyte Avatar answered Nov 06 '22 09:11

mobyte


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.

like image 2
kotarak Avatar answered Nov 06 '22 09:11

kotarak