How many variables got created in total inside a loop using `let` - clojure

I wrote the following function to print a value for 10 times:
(defn test-let []
(loop [index 0]
(when (< index 10)
(let [x 2]
(println "Value of x: " x))
(recur (inc index)))))
My question is:
Did because of let inside the loop, 10 variables (representing the value 2) and only 1 symbol (x, that represent the variable that holds value 2) got created?
If 10 variables were created, at what point they qualify for garbage collection?

I think you are mixing up values and variables. In your example above, there are 10 values created each time in the loop and are bound to x each time. In Clojure, the local symbols (aka names) created by a let form are not variables (for example, like those top level symbols created by def). Inside a let the symbols are just directly bound to the values. See https://clojure.org/reference/special_forms#let for more. The Clojure compiler does locals clearing, and will generate code to remove references to local values once the locus of control leaves the local scope. See https://clojure.org/reference/compilation#_locals_clearing for more details. In your particular case of a value of 2 it probably does not mater since Clojure will use the primitive value directly. I presume you were asking for the more general case where the value that is bound to x may be bigger than just a primitive.

Related

Why are variables in list cormprehensions not considered is mutable state in clojure?

In Clojure every variable is immutable. But when i use list comprehension like in the case below, the elem variable seems to be mutable, because each time elem is overwritten by 1, then by 2 and then by 3 or it is not?
(for [elem [1 2 3]]
elem)
Is this a point where mutability is allowed or am i missing something?
"Mutation" refers to an existing variable changing its contents. You could observe this if you had a reference to a variable, looked at it once, noting its value as X, and then later looked at the same variable again, noting its value is now Y. That isn't what's happening in a list comprehension.
First, let's talk about one thing that I hope you will agree is not mutation: calling a function multiple times with different values. Suppose we have
(defn triple [x]
(* x 3))
If we write [(triple 1) (triple 2)], do we say that x has mutated? Of course not. There were two different invocations of the function triple, each with a different value for x, but those weren't the same variable: they were different instantiations of x.
A list comprehension is the same thing. The body is a function, which is evaluated once for each of the inputs. It doesn't look like a function, because there's no fn, but it really is one, both technically (it macroexpands into the body of a fn) and philosophically (it handles inputs the same way as our triple function above). (for [x xs] (f x)) is no different from writing (map f xs), which needs no mutation.
Usually when newcomers worry about mutation in Clojure, they are worried about let, which allows you to replace existing bindings:
(let [x 1
_ (prn x)
x 2]
(prn x))
This prints 1 2: doesn't this prove that x has mutated? No, it doesn't: the old x is still there, it's just shadowed so you can't refer to it anymore. You can prove this by using a function to let you refer to the old x:
(let [x 1
f (fn [] x)
x 2]
(prn (f) x))
This still prints 1 2 even though both prints happen after x was bound to 2. This is because f still sees the old x. The new x is an unrelated variable with the same name; you might as well have called it y and renamed all references to it.
The distinction between value and identity, as described here, is important. If an identity appears to change, it is because it becomes associated with different state values over time.
If you have a C/C++ background, it may help to think that elem behaves like a non-const pointer which points at const objects.
If you have a Python/Java background, it might help to think that the values in the collection you are traversing are immutable.
In any case, the immutability question is an assertion about the elements in the collection, not about elem.

What should we call an object declared in a clojure prog?

When we talk about a clojure (or other lisp) prog, what should we say when refer an object declared in it? For example:
(let [a ...
Of course, if a is a function, we say function a, but what should we say when it's not a function? Form? Data? Symbol? Literal?
Generally, we say those things in other prog language variables or objects.
The let special form creates bindings between symbol(s) and a value.
The official documentation for let actually uses the vocabulary and wording that you are looking for and should use, specifically the Binding Forms section sheds more light to the subject:
The basic idea is that a binding-form can be a data structure literal containing symbols [or just a single symbol] that get bound to the respective parts of the init-expr.
I think the question mixed up two things, or at least didn't make it clear that they're different.
As the other answers so far indicated, "a" is a symbol, which evaluates to something else. So when we talk about a, we could mean the symbol, or the something else. And we could even mean the var that is an intermediary between the symbols and the something else. (See the page linked by Guillermo Winkler for more on the var/symbol relationship, which I'll leave in the background.)
A symbol is never a function, but it can have a function as its value. When you call a function, you are just using its value in a special way. You can even set the values of built-in functions to other values:
(def + -)
WARNING: + already refers to: #'clojure.core/+ in namespace: user, being replaced by: #'user/+
#'user/+
user=> (+ 5 2)
3
user=> (def - "This used to be the minus function")
WARNING: - already refers to: #'clojure.core/- in namespace: user, being replaced by: #'user/-
#'user/-
user=> -
"This used to be the minus function"
I gave + the value of -, and then made -'s value a string. (Yes, there were warnings, but it worked.) The fact that functions are just values of symbols is a way in which Clojure differs from many other languages. (Scheme is similar. Common Lisp is similar, but in a more complicated way.)
So the symbol is just the symbol. And it usually has a value, which may be a function, or a number, or a string, or a keyword, or anything that can be a value in Clojure--vectors, lazy sequences, lists (which may be Clojure code), or even another symbol (even the same one: (def a 'a).) You could call some of these things data if that's useful in a particular context. It's sometimes reasonable to describe functions as data in Clojure.
(def add-fns [#(+ 1 %) #(+ 2 %) #(+ 3 %)]) ;=> #'user/add-fns
add-fns ;=> [#object[user$fn__1178 0x71784911 "user$fn__1178#71784911"] #object[user$fn__1180 0x45ed957d "user$fn__1180#45ed957d"] #object[user$fn__1182 0x7838c8c5 "user$fn__1182#7838c8c5"]]
add-fns is a vector of functions. What should we call the functions that are elements of the vector? Aren't they data in some sense, if we use them like data? We can map a function over them, or reorder them, for example:
(map #(% 10) add-fns) ;=> (11 12 13)
(map #(% 10) (reverse add-fns)) ;=> (13 12 11)
Each of those expressions takes each function in add-fns and calls it with 10 as its argument, returning the results in a sequence.
Exception: macros don't follow the same rules:
user=> and
CompilerException java.lang.RuntimeException: Can't take value of a macro: ...
Some of the Java interop tricks don't follow the same rules, either.
a is always a symbol, independently of the value bound to it (whether it's a function or a number or anything else)
There's a previous answer on Clojure symbols that may clarify things a little bit more here: Symbols in Clojure
And remember symbols are not the same thing as vars

Questions about Vars 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%.

Embedding arbitrary objects in Clojure code

I want to embed a Java object (in this case a BufferedImage) in Clojure code that can be evald later.
Creating the code works fine:
(defn f [image]
`(.getRGB ~image 0 0))
=> #'user/f
(f some-buffered-image)
=> (.getRGB #<BufferedImage BufferedImage#5527f4f9: type = 2 DirectColorModel: rmask=ff0000 gmask=ff00 bmask=ff amask=ff000000 IntegerInterleavedRaster: width = 256 height = 256 #Bands = 4 xOff = 0 yOff = 0 dataOffset[0] 0> 0 0)
However you get an exception when trying to eval it:
(eval (f some-buffered-image))
=> CompilerException java.lang.RuntimeException: Can't embed object in code, maybe print-dup not defined: BufferedImage#612dcb8c: type = 2 DirectColorModel: rmask=ff0000 gmask=ff00 bmask=ff amask=ff000000 IntegerInterleavedRaster: width = 256 height = 256 #Bands = 4 xOff = 0 yOff = 0 dataOffset[0] 0, compiling:(NO_SOURCE_PATH:1)
Is there any way to make something like this work?
EDIT:
The reason I am trying to do this is that I want to be able to generate code that takes samples from an image. The image is passed to the function that does the code generation (equivalent to f above), but (for various reasons) can't be passed as a parameter to the compiled code later.
I need to generate quoted code because this is part of a much larger code generation library that will apply further transforms to the generated code, hence I can't just do something like:
(defn f [image]
(fn [] (.getRGB image 0 0)))
Not sure what you need it for, but you can create code that evals to an arbitrary object using the following cheat:
(def objs (atom []))
(defn make-code-that-evals-to [x]
(let [
nobjs (swap! objs #(conj % x))
i (dec (count nobjs))]
`(nth ~i #objs)))
Then you can:
> (eval (make-code-that-evals-to *out*))
#<PrintWriter java.io.PrintWriter#14aed2c>
This is just a proof of concept and it leaks the objects being produced - you could produce code that removes the reference on eval but then you could eval it only once.
Edit: The leaks can be prevented by the following (evil!) hack:
The above code bypasses eval's compiler by storing the object reference externally at the time the code is generated. This can be deferred. The object reference can be stored in the generated code with the compiler being bypassed by a macro. Storing the reference in the code means the garbage collector works normally.
The key is the macro that wraps the object. It does what the original solution did (i.e. store the object externally to bypass the compiler), but just before compilation. The generated expression retrieves the external reference, then deletes to prevent leaks.
Note: This is evil. Expansion-time of macros is the least desirable place for global side-effects to occur and this is exactly what this solution does.
Now for the code:
(def objs (atom {}))
Here's where will temporarily store the objects, keyed by unique keys (dictionary).
(defmacro objwrap [x sym]
(do
(swap! objs #(assoc % sym x) ) ; Global side-effect in macro expansion
`(let [o# (#objs ~sym)]
(do
(swap! objs #(dissoc % ~sym))
o#))))
This is the evil macro that sits in the generated code, keeping the object reference in x and a unique key in sym. Before compilation it stores the object in the external dictionary under the key sym and generates code that retrieves it, deletes the external reference and returns the retrieved object.
(defn make-code-that-evals-to [x]
(let [s 17] ; please replace 17 with a generated unique key. I was lazy here.
`(objwrap ~x ~s)))
Nothing fancy, just wrap the object in the evil macro, together with a unique key.
Of course if you only expand the macro without evaluating its result, you'll still get a leak.
I guess you would need to write a macro that takes the object (or a way to create the required object) at compile time, serialize that object in binary format (byte array) and the output of the macro should be - a symbol that refer to the byte array and a function that can be used to get the object from the serialized data by de-serializing it.
why not:
(defmacro m [img] `(.getRGB ~img 0 0))
then u can write: (m some-buffered-image)
The difference is that f is a function, so its argument will be evaluated before its body being evaluated. Thus the image object itself will be placed within the generated code. But for macros, their arguments will not be evaluated. So only the symbol some-buffered-image will be placed within the code. The generated code will be: (.getRGB some-buffered-image 0 0). Just like u write the source code directly. I think that's what u want.
But why can't I place an object in the generated code? The answer is: yes, u can. What the exception message says is not the truth. u can embed some kinds of objects in generated code, but not all kinds of them. They include symbol, number, character, string, regex patten, keyword, boolean, list, map, set etc. All these objects will be understood by the Clojure compiler. They are like key words, operators and literals in other languages. u can't require the Clojure compiler knows all kinds of objects, just like u can't require a C or Java compiler knows all words not included by its syntax.

How does Lisp dynamically assign symbols? Underlying data structure/mechanism of a Lisp symbol?

Lisp allows you to define symbols such as A and B in a list like
(setf mylist '(+ 1 2 A))
You can then go back at any time and set A to a value, for ex. (set 'A 100). At this point you can do (eval mylist) and get back 103. You can then repeatedly reassign A to any new value.
It seems Lisp is saving both the literal "A" (name of the symbol) and it's assigned value. This allows dynamic variable assignment/reassignment. It's kind of like a look up list. What is the underlying data structure or mechanism that allows this?
EDIT: Specifically, how this done internally (or externally since packages appear to be directly involved)? Looking for an in-depth technical answer that focuses on how it's implemented in Lisp-2.
Note that '(+ 1 2 A) is not a variable, but the form (quote (+ 1 2 A)) which evaluates to an object. The A inside the list is a symbol, but it is not a variable.
A variable is a storage location denoted by a symbol.
Re: How does a language like Lisp do this kind of evaluation at run-time?
(Common) Lisp has two kinds of variables: dynamic and lexical. The dynamic variables can be evaluated at run time in the sense that you can take a symbol and determine whether it has a dynamic variable binding, and retrieve or assign that binding.
Lexical variables are the ones that are "baked" at compile time: there is no portable way to reflect over them by name.
Both kinds of variables are useful for different purposes.
A dynamic variable can be stored in a location that is associated with a symbol, called its value cell. (This term actually appears in ANSI Common Lisp). The symbol is used as a kind of key to retrieve the cell (if it has one). For instance a value cell could be the cdr field of some cons cell that is stored in a hash table where the keys are symbols. Various implementations are possible.
There is a complication in that Lisp supports local rebinding of dynamic variables: i.e. you can use let or other binding constructs to create local bindings for dynamic variables which hide any existing binding. When the construct exits (in any manner: including a non-local exit via throw, etc) the hidden binding is restored. This dynamic scoping has to be implemented somehow and it means that a dynamic variable lookup is not necessarily just chasing a pointer from the symbol to a value cell.
A further complication is that users of multi-threaded Lisps want to have per-thread binding of dynamic variables.
There may be more info here: http://en.wikipedia.org/wiki/Scope_%28computer_science%29#Dynamic_scoping
In Common Lisp symbols are objects in their own right, capable of having named properties with values associated with them. Symbols are created (interned in current package) on read, like so:
> 'a
A
You can inspect them with (describe 'a) or (inspect 'a) (using CLISP here). You can set this symol with (set 'a 1). But you can also call (defun a (x) (+ 1 x)) after that. Inspecting the symbol 'a now reveals that it holds both a value, and a function definition at the same time. That reflects Common Lisp having separate namespaces for variables' values, and functions. Symbols store this extra information in their property lists:
[19]> (symbol-value 'a)
1
[20]> (symbol-function 'a)
#<FUNCTION A (X) (DECLARE (SYSTEM::IN-DEFUN A)) (BLOCK A (+ X 1))>
[21]> (symbol-plist 'a)
(SYSTEM::DEFINITION
((DEFUN A (X) (+ X 1)) .
#(NIL NIL NIL NIL ((DECLARATION OPTIMIZE DECLARATION)))))
[44]> (setf (get 'a 'prop1) 12)
12
[45]> (symbol-plist 'a)
(PROP1 12 SYSTEM::DEFINITION
((DEFUN A (X) (+ X 1)) .
#(NIL NIL NIL NIL ((DECLARATION OPTIMIZE DECLARATION)))))
See also
http://www.lispworks.com/documentation/HyperSpec/Body/f_get.htm#get
http://www.lispworks.com/documentation/HyperSpec/Body/f_intern.htm#intern