Questions about Vars Clojure
I am new to Clojure and I read that it is a functional language. It says Clojure has no variables, still when I find (def n 5) what's the difference between it and a variable?
I can change the value of var after, is this really different from a variable? I don’t understand the difference.
source to share
Assuming by variable
you mean a reference to a mutable storage location, my guess is that the main difference (depending on which language you are comparing) is that if you are dynamically rebuilding var
in Clojure, it is simple.
But the long answer is that you don't normally use var
in Clojure unless you really need a reference to a mutable storage location.
Clojure supports immutability and programming by using values instead of references.
You can watch Rich Hickey about the meaning.
The summary will be when you program in Clojure that you have values, not references to locations that might change (maybe even changed by another thread).
So.
(let [a 1
_ (println a) => prints 1
a 2
_ (println a) => prints 2
])
Even if you get the illusion of a "change a
" in this code, you are not changing the "old" a
value, you just have a new value. (if someone looked at the first definition, they would still see the value 1).
In fact you can see that the sequence of assignments as a compound function calls where a
is replaced in scope, but is not the same "variable" at all.
((fn [a]
(println a) => prints 1
((fn [a]
(println a) => prints 2
) 2) 1)
However, if you need to have variable storage with a potentially large number of threads that access the shared storage, Clojure's gives you vars
, atoms
, refs
etc.
source to share
It is not true that Clojure has no variables, i. e. replaceable links. However, they are not used for storage and retrieval during calculations, which can be modeled as pure mathematical functions.
Immutability is about defining specific values instead of references that one or the other might change. Just like 1
is a value that you cannot change, in Clojure a vector [3 2]
is a value that you cannot change either. E. g. if your algorithm needs to add 1
to this vector, it needs to create a new vector, leaving the old one, and in imperative languages you can simply "change" the vector, breaking all potentially relying on it. Pushing out immutability is that you no longer need to worry about it, and your code becomes less error-prone.
Clojure implements immutable data structures in such a way that such newly created values efficiently use most of the memory of the values on which they are based. They provide nearly the same performance characteristics as their mutable counterparts, both for reading and writing (i.e. new versions). You can read more about it here , and Rich Hickey makes a great explanation in this conversation with Brian Beckman.
source to share
Think of def as defining a constant. This can be changed by calling def , but you shouldn't .
Loops to variables agents that are thread safe.
(def counter (agent 0))
(send counter inc)
@counter
;;=> 1
You can also access the variable in the Java class.
New class
(def object (ClassName.))
Se value
(.fieldName object)
Set value
(set! (.fieldName object) 5)
The "whole" point of not having variables is to make the program automatic thread-safe. This is because a thread error "always" fails on that thread 1, showing that variable a is 1, and thread b reports that a is 2, and then something fails. This is also the rationale for using pure functions - no variables "no" threading problem.
See also this question: Clojure differences between Ref, Var, Agent, Atom, with examples and this Clojure: vars, atom and refs (oh mine) .
Treat "" as 80% or more - not 100%.
source to share