I'm trying to define several constant variables in clojure. Is there a way to define all of them in one def statement? Or must I define each one separately?

In any programming language (C++ Java) you may expect to be able to do the following

    const int x, y, z;
    x = y = z = 0;

However, in clojure I'm having trouble doing something similar with the def declaration. I've tried something based off of the 'let' syntax:

    (def ^:const [x 2 y 3 z 8])

and something like

    (def ^:const x 2 y 3 z 8)

but none of these work. Must I separately define each variable?

  • note that ^:const in clojure does not do what const does in other languages, in particular vars are always mutable and the ^:const metadata tells the compiler it can inline a primitive value but does not prevent you from erroneously changing it anyway – noisesmith Feb 21 '16 at 18:29
  • Oh. Well, is there a way to create a final immutable value in clojure?? – Lucas Rudd Feb 21 '16 at 20:54
  • 1
    Sure, we have immutable data structures for example. But vars are a mutable container. – noisesmith Feb 21 '16 at 20:57
  • I'd like to add that, while vars are mutable, you generally don't go around changing their (root) values programmatically, except sometimes in dynamic development. – Sam Estep Feb 21 '16 at 21:38
  • Your C/C++ is wrong. The nearest I can get past the compiler is ` const int x = 0, y = 0, z = 0;`, which separately defines each variable. – Thumbnail Feb 21 '16 at 22:04

If you want a separate Var for x, y, and z, you must define each one separately:

(def x 2)
(def y 3)
(def z 8)

You could easily write a macro to define multiple constants at once if this is too cumbersome:

(defmacro defs
  [& bindings]
  {:pre [(even? (count bindings))]}
     ~@(for [[sym init] (partition 2 bindings)]
         `(def ~sym ~init))))

(defs x 2 y 3 z 8)

If these three constants are related, though, you could instead define a map with an entry for each number:

(def m {:x 2, :y 3, :z 8})

Depending on your use case, you may even find it valuable to define them as a vector instead:

(def v [2 3 8])

Your Answer

