Why does the clojure repl show that a var is associated with a symbol, after it's been unmapped? - clojure

Let's say I create a variable, x, in a Clojure namespace, store the associated var in another variable (y), and then unmap x:
(ns user)
(def x 0)
(def y (var x))
(ns-unmap 'user 'x)
If I evaluate y in the REPL, it prints #'user/x, even though the symbol user/x is not associated with this variable anymore.
user=> y
#'user/x
user=> (deref y)
0
user=> (deref #'user/x)
Syntax error compiling var at (REPL:0:0).
Unable to resolve var: user/x in this context
Things get really confusing if I create a new variable associated with the symbol x:
(def x 1)
(def z (var x))
Now, the repl prints both y and z as #'user/x, even though those variables point to different var objects:
user=> y
#'user/x
user=> (deref y)
0
user=> z
#'user/x
user=> (deref z)
1
user=> (= z y)
false
Why does the REPL print #'user/x when evaluating y here?

To think properly about this, you need to understand how vars and namespaces work in Clojure.
A var is a mutable storage location, optionally named by a namespaced symbol.
A namespace is a map from symbol to var.
If namespace n has a definition named s, then it maps the symbol n/s to a var that is named by n/s.
So, you defined x, yielding a var (call it v) labeled user/x and containing 0, and stored in the namespace user. Then you removed that mapping from the user namespace. But the var v still exists, and still knows it's called user/x. So you can still look at it by traversing through y, which has of course saved the actual var object, and no longer cares what namespace was used to look up the var. You can, e.g. print its name and dereference it to see the value 0 that was locked in there.
You later define a new var named x in the user namespace, yielding a new var that knows it's referred to by user/x. But it's a distinct var, so they can hold different values, and the user namespace now points to a different var than the one you stored in y.

Related

Unable to resolve symbol: Example in this context clojure 1.10

I am a beginner with Clojure and I received this error while trying to write code in Clojure:
; Syntax error compiling at (src/com/playground/core.clj:17:1).
; Unable to resolve symbol: Example in this context
Here is my code
(ns com.playground.core
(:gen-class))
;; This program displays Hello World
(defn Example []
;; The below code declares a integer variable
(def x 1)
;; The below code declares a float variable
(def y 1.25)
;; The below code declares a string variable
(def str1 "Hello")
(println x)
(println y)
(println str1))
(Example)
I pulled this directly from tutorialspoint and tried to find other people who had the same error but could not find anybody else.
I guess you didn't evaluate that function. Open REPL for this project, evaluate definition for Example and then evaluate (Example).
As you can already see in comments, this code is very bad and you shouldn't learn from that tutorial. But from a beginner point of view, it may be helpful to see what exactly is wrong:
naming conventions: names of functions should be dash-separated-lowercase-words, so no Example, but example.
already mentioned def inside defn. Def creates a global variable, don't use it inside any other definitions. If you need to create some variables inside function, use let.
integer variable and float variable. Clojure uses long and double and created variables will have exactly these types- you can check it yourself with function type.
repeated println (it'll work, but you can also use clojure.string/join with vector and only one println to get the same result)
Improved code:
(defn example []
(let [x 1
y 1.25
str1 "Hello"]
(println (clojure.string/join
"\n"
[x (type x) y (type y) str1]))))
(example)
=>
1
class java.lang.Long
1.25
class java.lang.Double
Hello
You can't declare a definition inside a function.
You need to declare these symbols (variable in other langs) outside. Something like that.
(ns com.play
ground.core
(:gen-class))
(def x 1)
(def y 1.25)
(def str1 "Hello")
(defn Example []
(println x)
(println y)
(println str1))
(Example)
So, when you do it, you're declaring x y and str1 as global and it's not a good practice.
To keep the context of these symbols only inside the function, you need to use the let approach.
(ns com.playground.core
(:gen-class))
(defn Example []
(let [x 1
y 1.25
str1 "Hello"]
(println x)
(println y)
(println str1)))
(Example)
An extra tip is to avoid using camel-case as a way of declaration naming.
Consider to use kebab-case :)
(ns com.playground.core
(:gen-class))
(defn example-function []
(let [x 1
y 1.25
str1 "Hello"]
(println x)
(println y)
(println str1)))
(example-function)

Clojure with-local-vars not creating thread-local bind?

In the documentation of with-local-var
varbinding=> symbol init-expr
Executes the exprs in a context in which the symbols are bound to
vars with per-thread bindings to the init-exprs. The symbols refer
to the var objects themselves, and must be accessed with var-get and
var-set
But why thread-local? returns false?
user=> (with-local-vars [x 1] (thread-bound? #'x))
false
Because, in your example, x is a local binding to a variable containing a var. #'x is shorthand for (var x), which will resolve x as a global in the current namespace. Since with-local-vars doesn't affect the global x, thread-bound? returns false.
You need to use x (not (var x)) to refer to the var created by with-local-vars. For example:
(def x 1)
(with-local-vars [x 2]
(println (thread-bound? #'x))
(println (thread-bound? x)))
Outputs:
false
true
Also, note that with-local-vars does not dynamically rebind x. x is only lexically bound to the new var within the with-local-vars block. If you call a function that refers to x, it will refer to the global x.
If you want to dynamically rebind x, you need to use binding and make x dynamic:
(def ^:dynamic x 1)
(defn print-x []
(println x))
(with-local-vars [x 2]
(print-x)) ;; This will print 1
(binding [x 2]
(print-x)) ;; This will print 2

How to get name of argument in Clojure?

I would like to get the name of a var defined outside a function, from within a function. The name should be the name that I used at the scope of the original definition, not any nested bindings where I'm actually trying to use the name.
So I would like to do something like (academic example):
(defn f1 [x1] (println "hello, you passed var name >>" (get-var-name x1) "<<")
(defn f2 [x2] (f1 x2))
(defn f3 [x3] (let [zzz x3] (f2 zzz))
(def my-var 3.1414926)
(f3 my-var)
user> hello, you passed var name >>my-var<<
I'm able to do this macro based on some stuff i found:
(defmacro get-var-name [x]
`(:name (meta (var ~x))))
This works when called eg from the REPL, but compiler chokes when called from an "inside" scope eg
(defn another-func [y]
(get-var-name y))
Compiler says "saying Unable to resolve var y". (macroexpand...) shows it's trying to find local variable y in the current namespace, rather than the original variable in the current namespace. I think (var...) looks for namespace vars only, so this prevents the macro from working either within a function or another binding such as let.
I think I'm stuck having to manually get the variable name from the same scope where I define the variable and pass it along as an extra parameter. Is there a more elegant way to pass var name information through a chain of bindings to the point where it's used? That would be bad-ass.
thanks
It's not possible to get the name of the var used in an outside scope within a function - the function only receives a the value passed as a parameter at runtime, not the var itself.
The only thing you could potentially do is use macros instead of functions at each level. This allows you to pass the var itself through the different macros at compile time:
(defmacro f1 [x1] `(println "hello, you passed var name >>" ~(str x1) "<<"))
(defmacro f2 [x2] `(f1 ~x2))
(defmacro f3 [x3] (let [zzz x3] `(f2 ~zzz)))
(f3 my-var)
=> hello, you passed var name >> my-var <<
This is pretty ugly - you certainly don't want to be writing all of your code with macros just to get this feature! It might make sense though in some specialised circumstances, e.g. if you are creating some kind of macro-based DSL.
You can pass the actual var to the function rather than the var resolved value using #' reader macro as shown below:
user=> (defn f1 [x1] (println "hello, you passed var name >>" (:name (meta x1)) "<<"))
#'user/f1
user=> (defn f2 [x2] (f1 x2))
#'user/f2
user=> (defn f3 [x3] (let [zzz x3] (f2 zzz)))
#'user/f3
user=> (def my-var 3.1414926)
#'user/my-var
user=> (f3 #'my-var)
hello, you passed var name >> my-var <<
In case you want the value bound to the var, you can use var-get function to do so.
Why not just pass (get-var-name _symbol-here_) to functions where you will want to use the var name inside the body? For example, using exactly the same definitions of get-var-name, f2, f3, and my-var which you have given above (but changing f1 slightly):
(defmacro get-var-name [x]
`(:name (meta (var ~x))))
(defn f1 [x1] (println "hello, you passed var name >>" x1 "<<"))
(defn f2 [x2] (f1 x2))
(defn f3 [x3] (let [zzz x3] (f2 zzz)))
(def my-var 3.1414926)
=> (f3 (get-var-name my-var))
hello, you passed var name >> my-var <<
=> nil
Maybe sometimes, you will also want to refer to the value that the symbol refers to in the function body. For example, let's say in f1 you want to also print out the value referenced by that var name. Here's how you could do that:
(defn f1 [x1] (println "hello, you passed var name >>" x1 "<<"
"\nwhich refers to value >>" #(resolve x1) "<<"))
=> (f3 (get-var-name my-var))
hello, you passed var name >> my-var <<
which refers to value >> 3.1414926 <<
=> nil
Note the #(resolve x1)--this is the thing returning the value that my-var refers to (and in turn my-var is the value referred to by x1).
Also, I want to mention that your current implementation of get-var-name will throw Exceptions when the argument passed to it is either not a symbol, or is a symbol, but is not currently bound to a value. Is this the behavior you want?
If what I propose does not answer your question, then it seems like you don't want to have to pass (get-var-name _symbol-here_) to the functions that may end up using the var name, but rather for some reason really want to be able to do the (get-var-name ...) from within the function body. If this is the case, why is it that you want to be able to do it that way? Or, if you feel I have not answered your question for some other reason, what is that reason?

What's the difference between var and quote?

What's meaning difference between var and quote in Clojure? For example, (var a) and (quote a).
The official site has the below documents, but what's the difference of var object and the value for the symbol? I am confused.
(var symbol)
The symbol must resolve to a var, and the Var object itself (not its value) is returned
(quote a) returns a symbol (clojure.lang.Symbol) - it effectively does the same as 'a. It's worth reading a bit more about the Clojure reader to find out a bit more about symbols. Example:
(quote a)
=> a
(var a) returns the var (clojure.lang.Var) represented by the symbol a in the current namespace. You'll get an error if a is not defined in the current namespace. Example:
(var a)
=> #<CompilerException java.lang.RuntimeException: Unable to resolve var: a in this context, compiling:(NO_SOURCE_PATH:1)>
(def a 1)
(var a)
=> #'user/a
That's the technical definition - but here's the intuition behind it: a symbol is a name, which can be used to look up a var in a given namespace. A var itself is a kind of reference that can hold any kind of Clojure value. So a symbol identifies a var which contains a value.
Consider this:
; #'x a reader short-cut for (var x), and 'x is a short-cut for (quote x)
(def x)
(binding [x 1] (var-set #'x 2) (list (var x) (quote x) x))
Which evaluates to something like (comments added)
(
#'sandbox177857/x ; the variable itself - was passed to var-set
x ; the symbol x. same as 'x
2 ; last value in #'x
)
set! will take in (among other things) a Var or a symbol which resolves to a global name (var-set will only accept a Var). The reason why (var-set x ...) wouldn't have worked is that this would have resulted in the value of x being passed in (and not the Var called x).
Hope this helped. Happy coding.

Clojure def vs defn for a function with no arguments

I have written a program in clojure but some of the functions have no arguments. What would be the advantages of coding such functions as a "def" instead of a "defn" with no arguments?
(def t0 (System/currentTimeMillis))
(defn t1 [] (System/currentTimeMillis))
(t1)
;; => 1318408717941
t0
;; => 1318408644243
t0
;; => 1318408644243
(t1)
;; => 1318408719361
defs are evaluated only once whereas defns (with or without arguments) are evaluated (executed) every time they are called. So if your functions always return the same value, you can change them to defs but not otherwise.
(defn name ...) is just a macro that turns into (def name (fn ...) anyway, not matter how many parameters it has. So it's just a shortcut. See (doc defn) for details.
https://clojure.org/guides/learn/functions#_defn_vs_fn
The def special form creates a Var object identified by a symbol given as its first argument. Identification is created by associating the given symbol with a Var in a map called namespace.
The Var holds a reference to some value, which could be expressed (among others):
as a constant form, which always evaluates to its own value:
(def x 1)
x
;; => 1 ; x holds a reference to a number 1
as a function form, which at first is evaluated to its resulting value:
(def x (+ 2 2))
x
;; => 4 ; x holds a reference to a number 4
as a Java method form, which at first is evaluated to its resulting value:
(def x (System/currentTimeMillis))
x
;; => 1417811438904 ; x holds a reference to a number 1417811438904
x
;; => 1417811438904 ; still the same number!
as a lambda form (anonymous function), which at first is evaluated to a function object:
(def x (fn [] (System/currentTimeMillis)))
x
;; => #<user$x user$x#4c2b1826>
(x) ; function form, function evaluated
;; => 1417811438904
(x) ; function form, function evaluated
;; => 1417812565866
There is a simple rule for all of the above. In case of def special form an S-expression given as its second argument is recursively evaluated before binding is created, so the resulting Var is bound to the result of this evaluation.
Even fn is evaluated before, but its resulting value is a function object that holds a code. This code will be executed (and evaluated) each time the function is called. That's why there are different results.
The defn macro is just like def but internally it creates an anonymous function and then binds a Var object to it. Its second argument becomes a body of this function and it's not evaluated in a "regular" way. One could also say it is evaluated but as a lambda form – the result of the evaluation is a function object, not the result of some instant calculation.
So writing:
(defn fun [] 1)
Is synonymous to:
(def fun (fn [] 1))