Questions about Vars Clojure - clojure

I'm new in Clojure and i read that it is a functional language. It says that Clojure doesn't have variables, still when i find (def n 5), what's the difference between it and a variable?
I can change the value of the var after, so is it really that different from a variable? I don't understand the difference.

Assuming that by variable you mean a refer to a mutable storage location, I guess the main difference(depending against which language you compare) is that if you dynamically rebind the var in Clojure is on a per-thread basis.
But the long answer is that you don't usually use a var in Clojure unless you really need a reference to a mutable storage location.
Clojure favors immutability and programming using values instead of references.
You can watch Rich Hickey's talk about values.
A summary would be, when you're programming in Clojure what you have are values , not references to locations that may 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 "changing a" in that code, you're not changing the "old" a you just have a new value. (if someone would have looked at the first definition it would still be seeing the value 1).
Actually you can see that sequence of assignments as a composed function calls where a is being replaced in scope, but not the same "variable" at all.
((fn [a]
(println a) => prints 1
((fn [a]
(println a) => prints 2
) 2) 1)
None the less, if you need to have a mutable storage with potentially many threads accessing that storage, Clojure gives you vars, atoms, refs, etc.

It is not true that Clojure does not have variables, i. e. changeable references. They are however not used to store and look up during computations that can be modeled as pure mathematical functions.
The concept of immutability is that of dealing with concrete values instead of references that one or others can change. Just like 1 is a value that you can't change, in Clojure the vector [3 2] is value that you also can't change. E. g. if your algorithm is required to append 1 to that vector, it needs to create a new vector, leaving the old one intact, while in imperative languages you could just "change" the vector, breaking everything potentially relying on it. The takeaway of immutability is that you don't have to worry about that anymore and your code becomes less error prone.
Clojure implements immutable datastructures in a way that such newly created values efficiently reuse most memory of the values they are based on. They provide near the same performance characteristics as their mutable counterparts both for reading and writing (i. e. creating new versions). You may want to read more about that here and Rich Hickey does some excellent explaining in this conversation with Brian Beckmann.

Think about def as defining constant. It can be change by calling def again but you should not do it.
The closes thing to variables are agents which are thread safe.
(def counter (agent 0))
(send counter inc)
#counter
;;=> 1
You can also access the variable in Java class.
New class
(def object (ClassName.))
Se value
(.fieldName object)
Set value
(set! (.fieldName object) 5)
The "whole" point of of not having variables is to make program automatically thread safe. It is because thread error will "always" fail on that thread 1 wil tell the variable a is 1 and thread b tells that a is 2 and after that something fail. This is also reason to use pure functions - no variables "no" thread problem.
See also this question:Clojure differences between Ref, Var, Agent, Atom, with examples and this one Clojure: vars, atoms, and refs (oh my).
Treat "" as in 80% or more - not 100%.

Related

Why can I change immutable variables in Clojure?

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
To be precise, Clojure has immutable values, not immutable 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.

Is there a canonical way to name variables that would otherwise cause name collisions?

Say I'd like to name a variable seq, referring to some kind of sequence.
But seq is already a function in clojure.core, so if I try to name my variable seq, the existing meaning of seq will be overwritten.
Is there a canonical way in Clojure to name a variable that would otherwise have a name collision with a default variable?
(e.g., in this case, my-seq could be used, but I don't know whether that would be standard as far as style goes)
There is no "standard" way of naming things (see the quote and the related joke).
If it is a function of only one thing, I often just name it arg. Sometimes, people use abbreviations like x for a single thing and xs for a sequence, list, or vector of things.
For small code fragments, abbreviating to the first letter of the "long" name is often sufficient. For example, when looping over a map, each MapEntry is often accessed as:
(for [[k v] some-map] ; destructure key/val into k & v
...)
Other times, you may prefix it with a letter like aseq or the-seq.
Another trick I often use is to add a descriptive suffix like
name-in
name-full
name-first
(yes, there is a Clojure function name).
Note that if you did name it seq, you would create a local variable that shadowed the clojure.core/seq function (it would not be "overwritten"). I often just "let it slide" if the scope of the shadowing is limited and the name in question is clear & appropriate (key and val are often victims of this practice). For name, I would also probably just ignore the shadowing of clojure.core/name, since I rarely use that function.
Note that you can shadow your own local variables. This is often handy to coerce data in to a specific format:
(defn foo
[items]
; assume we need a sorted vector with no duplicates
(let [items (vec (sort (set (items))))]
...))
By shadowing the original items argument, we ensure the data is in the desired form without needing to come up with two good, descriptive names. When this technique doesn't quite fit, I often fall back to the suffix trick and just name them items-in and items or similar.
Sometimes a suffix indicating type is valuable, when multiple representations are required. For example:
items
items-set
items-vec
type-str
type-kw
type-sym
There are many other possibilities. The main point is to make it clear to the reader what is happening, and to avoid creating booby traps for the unaware.
When in doubt, add a few more letters so it is obvious to a new reader what is happening.
You won't override clojure.core/seq. You will be simply shadowing the var seq with your local bindings or vars. One can always use fully qualified name to use core seq.
Example:
;; shadow core seq
(def seq [1 2 3])
WARNING: seq already refers to: #'clojure.core/seq in namespace: user, being replaced by: #'user/seq
=> #'user/seq
;; local binding
(defn print-something [seq]
(prn seq)
(prn (var seq)))
=> #'user/print-something
;; use fully qualified name
(clojure.core/seq "abc")
=> (\a \b \c)
(print-something "a")
"a"
#'user/seq
=> nil
(prn seq)
[1 2 3]
=> nil
(var seq)
=> #'user/seq
But, its not a clean practice to shadow clojure.core vars as it might lead to buggy code. It does more harm than good if any. I usually name vars based on code context, like employee-id-seq, url-seq etc. Sometimes, it okay to use short names like x or s if usage scope is limited. You can also see clojure.core implementation to find more examples.
A good guide: https://github.com/bbatsov/clojure-style-guide#idiomatic-names
I also recommend clj-kondo plugin

Clojure let vs Common Lisp let

In Common Lisp, the let uses a list for a bindings, i.e:
(let ((var1 1)
(var2 2))
...)
While Clojure uses a vector instead:
(let [a 1
b 2]
...)
Is there any specific reason, other than readability, for Clojure to use a vector?
You can find Rich Hickey's argument at Simple Made Easy - slide 14, about 26 minutes in:
Rich's line on this was as follows
"Since we were talking about syntax, let’s look at
classic Lisp. It seems to be the simplest of syntax, everything is a
parenthesized list of symbols, numbers, and a few other things. What
could be simpler? But in reality, it is not the simplest, since to
achieve that uniformity, there has to be substantial overloading of
the meaning of lists. They might be function calls, grouping
constructs, or data literals, etc. And determining which requires
using context, increasing the cognitive load when scanning code to
assess its meaning. Clojure adds a couple more composite data literals
to lists, and uses them for syntax. In doing so, it means that lists
are almost always call-like things, and vectors are used for grouping,
and maps have their own literals. Moving from one data structure to
three reduces the cognitive load substantially."
One of the things he believes was overloaded in the standard syntax was access time. So vector syntax in arguments is related to the constant access time when you used them. He said:
Seems odd though as it only is valid for that one form...as soon as it is stored in a variable or passed in any way the information is 'lost'. For example...
(defn test [a]
(nth a 0)) ;;<- what is the access time of and element of a?
I personally prefer harsh syntax changes like brackets to be reserved for when the programmer has to switch mental models e.g. for embedded languages.
;; Example showing a possible syntax for an embedded prolog.
{size [],0}
{size([H|T],N) :- size(T,N1), N is N1+1}
(size '(1 2 3 4) 'n) ;; here we are back to lisp code
Such a concept is syntactically constant. You don't 'pass around' structure at runtime. Before runtime (read/macro/compile time) is another matter though so where possible it is often better to keep things as lists.
[edit]
The original source seems to have gone, but here is another record of the interview: https://gist.github.com/rduplain/c474a80d173e6ae78980b91bc92f43d1#file-code-quarterly-rich-hickey-2011-md

Is immutability in clojure different than pass-by-value?

I'm just getting started with Clojure and I have no fp experience but the first thing that I've noticed is a heavy emphasis on immutability. I'm a bit confused by the emphasis, however. It looks like you can re-def global variables easily, essentially giving you a way to change state. The most significant difference that I can see is that function arguments are passed by value and can't be re-def(ined) within the function. Here's a repl snippet that shows what I mean:
towers.core=> (def a "The initial string")
#'towers.core/a
towers.core=> a
"The initial string"
towers.core=> (defn mod_a [aStr]
#_=> (prn aStr)
#_=> (prn a)
#_=> (def aStr "A different string")
#_=> (def a "A More Different string")
#_=> (prn aStr)
#_=> (prn a))
#'towers.core/mod_a
towers.core=> a
"The initial string"
towers.core=> (mod_a a)
"The initial string"
"The initial string"
"The initial string"
"A More Different string"
nil
towers.core=> a
"A More Different string"
If I begin my understanding of immutability in clojure by thinking of it as pass-by-value, what am I missing?
Call-by-value and immutability are two entirely distinct concepts. Indeed, one of the advantages of variable immutability is that such variables could be passed by name or reference without any effect on programme behaviour.
In short: don't think of them as linked.
generally very little is "def"d in a clojure script/class, it's mostly used for generating values that are used outside of the class. instead values are created in let bindings as you need them in your methods.
def is used to define vars, as stated in Clojure Programming:
top level functions and values are all stored in vars, which are
defined within the current namespace using the def special form or one
of its derivatives.
Your use of def inside a function isn't making a local variable, it's creating a new global var, and you're effectively replacing the old reference with a new one each time.
When you move onto using let, you'll see how immutability works, for instance using things like seqs which can be used over without penalty of something else having also read them (like an iteration over a list would in java for instance), e.g.
(let [myseq (seq [1 2 3 4 5])
f (first myseq)
s (second myseq)
sum (reduce + myseq)]
(println f s sum))
;; 1 2 15
As you can see, it doesn't matter that (first myseq) has "taken" an item from the sequence. because the sequence myseq is immutable, it's still the same, and unaffected by the operations on it. Also, notice that there isn't a single def in the code above, the assignment happened in the let bindings where the values myseq, f, s and sum were created (and are immutable within the rest of the sexp).
Yes, immutability is different from pass-by-value, and you've missed a couple of important details of what's going on in your examples:
value mutation versus variable re-binding. Your code exemplifies re-binding, but doesn't actually mutate values.
shadowing. Your local aStr shadows your global aStr, so you can't see the global one -- although it's still there -- so there's no difference between the effects of (def a ...) and (def aStr ...) here. You can verify that the global is created after running your function.
A final point: Clojure doesn't force you to be purely functional -- it has escape hatches, and it's up to you to use them responsibly. Rebinding variables is one of those escape hatches.
just a note that technically Java, and by extension Clojure (on the JVM) is strictly pass by value. In many cases the thing passed is a reference to a structure that others may be reading, though because it is immutable nobody will be changing out from under you. The important point being that mutability and immutability happen after you pass the reference to something so, and Marcin points out they really are distinct.
I think of much of the immutability in Clojure as residing in (most of) the built-in data structure types and (most of) the functions that allow manipulating ... uh, no, modifying ... no, really, constructing new data structures from them. There are array-like things, but you can't modify them, there are lists, but you can't modify them, there are hash maps, but you can't modify them, etc., and the standard tools for using them actually create new data structures even when they look, to a novice, as if they're performing in-place modifications. And all of that does add up to a big difference.

Tokens and Erlang-like references in Clojure

I'm looking for data structure with the following features or way to emulate it in Clojure (via http://www.erlang.org/course/advanced.html#refs):
References are erlang objects with exactly two properties:
They can be created by a program (using make_ref/0), and,
They can be compared for equality.
Erlang references are unique, the system guarantees that no two references created by >different calls to make_ref will ever match. The guarantee is not 100% - but differs from >100% by an insignificantly small amount :-).
and particularly Name data type from Oz language (http://www.mozart-oz.org/documentation/tutorial/node3.html):
The only way to create a name is by calling the procedure {NewName X} where X is assigned >a new name that is guaranteed to be worldwide unique. Names cannot be forged or printed.
While "unforgeable" value sounds suspicious, especially in dynamic language like Clojure this is what I am looking for. Van Roy uses this feature in CTM to create so called "secure data structures" and later on, for secure token shared between trusted entities in code:
declare NewWrapper in
proc {NewWrapper ?Wrap ?Unwrap}
Key={NewName}
in
fun {Wrap X}
fun {$ K} if K==Key then X end end
end
fun {Unwrap C}
{C Key}
end
end
% A secure declarative unbundled Stack
declare NewStack Push Pop IsEmpty in
local Wrap Unwrap in
{NewWrapper Wrap Unwrap}
fun {NewStack} {Wrap nil} end
fun {Push S E} {Wrap E|{Unwrap S}} end
fun {Pop S E}
case {Unwrap S} of X|S1 then E=X {Wrap S1} end
end
fun {IsEmpty S} {Unwrap S}==nil end
end
Can this behavior be emulated in Clojure? This way I can assure e.g. that programmer can unwrap a data structure if and only if I have granted him a token. I am aware that it can be insecure nonetheless I would like to find the solution that is functionally equivalent to Van Roy one's and at least hard to circumvent by programmer.
The next requirement would be to base on pure Clojure and not JVM magic - so no "token = new Object()" etc. For example, function value looks like a good candidate because AFAIK after (defn f [] nil) then (identical? f x) evaluates to true only for x=f and and f is not a subject to memory optimizations like other constructs in functional language (or is it?). However, this approach may have further consequences I am not aware of. Could {NewName} from the above example could be just replaced with new anonymous function (provided non-distributed environment)?
gensym is guaranteed to produce a unique symbol that can be used to name things.
user> (gensym 'token)
token3783
user> (gensym 'token)
token3788
user> (gensym 'token)
token3793
user> (gensym 'token)
user> (def mine (gensym 'token))
#'user/mine
user> (def yours (gensym 'token))
#'user/yours
user> (= mine yours)
false
user> (= mine mine)
true