Why can I change immutable variables in Clojure?

Viewed 80

I come from the Javascript world where const is used to declare immutable variables.

The definition of a immutable variable is explained in the same way in Clojure.

However, this is allowed:

(def cheese "I like cheese")

...
...

(def cheese "Actually, I changed my mind)

When I run this, the repl gives me actually, I changed my mind.

In JS, it will throw an error because a const cannot be changed.

I would appreciate it if someone explained where my understanding of immutable variables is incorrect in the clojure world?

Thanks

2 Answers

To be precise, Clojure has immutible values, not immutible variables. After all, the name Var is shorthand for "variable".

Imagine the number 5. You never need to worry about who "owns" it, or that someone might change its definition. Also, there can be many copies of that number used for many purposes in many parts of your program. Clojure extends this idea to collection values such as the vector [1 2 3] or the map {:first "Joe" :last "Cool"}.

Having said that, in Clojure a Var is normally used for a global "constant" value that is never changed (although it could). Using a Clojure Atom (global or local) is normal for values that do change. There are many other options (functions like reduce have an internal accumulator, for example).

This list of documentation sources is a good place to start, esp the books "Getting Clojure" and "Brave Clojure".

As Alan mentions, Clojure has immutable values, not immutable variables.

When you execute

(def x 42)

what happens is that a Clojure Var is created, the Var is bound to the name (aka symbol) x, and the immutable value 42 is placed inside the Var. A Var is a container of values. Typically, only one value is ever placed in a Var. But, as in your example, there can be different immutable values placed inside the Var at different times.

Reading Clojure Vars and the Global Environment might be helpful.

Related