How to circumvent the immutability of def, and should I?


#1

hi,
I am doing some preliminary stuff on

http://iloveponies.github.io/120-hour-epic-sax-marathon/index.html

and i have a question concerning def

when
(def stuff [1 2 3 4] )

(conj stuff 9)

[1 2 3 4 9]
(stuff)
[1 2 3 4]

why doesn’t it take the 9, i assume because its immutable?

And if I do want to add something to that vector do i then have to rename it like this:
(def newstuff ( conj stuff 9)) or is there another way?

best,

Alexander


#2

Hi @Al_x,

Thanks for the question.

You should avoid using def to change the value of a Var. They are just there to support redefinition while you’re developing. At runtime, the Var should not change.

However, Clojuer does provide a lot of tools for creating a mutable value such as you want here. If you need something to change over time, you are suggested to use one of the Concurrency Primitives such as Atoms, Refs, or Agents. In this simple case I would suggest Atoms, since they are the simplest to get started with. You can read about them here: https://purelyfunctional.tv/guide/clojure-concurrency-the-ultimate-guide/#atom

Short bit of code to demonstrate:

(def stuff (atom [1 2 3 4]))

(prn @stuff) ;; => [1 2 3 4]

(swap! stuff conj 9)

(prn @stuff) ;; => [1 2 3 4 9]

Rock on!
Eric


#3

Hi,
cool thanks i will start playing with that!

best,

Al_x


#4

This article is only tangentially related to your original question, but it describes an unconventional way of using def for debugging. This shows that some of these rules are meant to broken under the right circumstances during development.


#5

Hi Jay_Martin,

I was a bit skeptical about the article, why not just download cider but i was trouble shooting a simple program yesterday and realized that it could sometimes be helpful. :slight_smile: