I'm always a bit confused about Symbols and Vars in Clojure.
For example, is it safe to say that + is a symbol which is used to denote a var, and this var points to a value which is a function that can add numbers?
So what happens, step by step when I just enter "+" in a REPL?
The symbol gets qualified to a namespace, in this case clojure.core
Then in some symbol table there is the information that + refers to a var
When this var is evaluated, the result is a function-value?
There's a symbol + that you can talk about by quoting it:
user=> '+
+
user=> (class '+)
clojure.lang.Symbol
user=> (resolve '+)
#'clojure.core/+
So it resolves to #'+, which is a Var:
user=> (class #'+)
clojure.lang.Var
The Var references the function object:
user=> (deref #'+)
#<core$_PLUS_ clojure.core$_PLUS_#55a7b0bf>
user=> ##'+
#<core$_PLUS_ clojure.core$_PLUS_#55a7b0bf>
(The # sign is just shorthand for deref.) Of course the usual way to get to the function is to not quote the symbol:
user=> +
#<core$_PLUS_ clojure.core$_PLUS_#55a7b0bf>
Note that lexical bindings are a different mechanism, and they can shadow Vars, but you can bypass them by referring to the Var explicitly:
user=> (let [+ -] [(+ 1 2) (##'+ 1 2)])
[-1 3]
In that last example the deref can even be left out:
user=> (let [+ -] [(+ 1 2) (#'+ 1 2)])
[-1 3]
This is because Var implements IFn (the interface for Clojure functions) by calling deref on itself, casting the result to IFn and delegating the function call to that.
The visibility mechanism used when you define private functions with defn- is based on metadata on the symbol. You can bypass it by referring directly to the Var, as above:
user=> (ns foo)
nil
foo=> (defn- private-function [] :secret)
#'foo/private-function
foo=> (in-ns 'user)
#<Namespace user>
user=> (foo/private-function)
java.lang.IllegalStateException: var: #'foo/private-function is not public (NO_SOURCE_FILE:36)
user=> (#'foo/private-function)
:secret
See the documentation for namespaces:
Namespaces are mappings from simple (unqualified) symbols to Vars and/or Classes. Vars can be interned in a namespace, using def or any of its variants, in which case they have a simple symbol for a name and a reference to their containing namespace, and the namespace maps that symbol to the same var. A namespace can also contain mappings from symbols to vars interned in other namespaces by using refer or use, or from symbols to Class objects by using import.
So basically your steps 1 and 2 are unified: the namespaces are the symbol tables.
And regarding step 3: I like the definition for variables that they're combinations of names of values. The symbol is the variable's name, and evaluating it will result in its value.
This answer is not very different from the other ones, it just doesn't assume you originally wish to learn several new functions and concepts just to understand what's going on:
+ is a symbol sitting in clojure.core which is by default accessible to your code.
When used in your code without any very advanced intents such as quoting it or finding out its class ― clojure will seek the Var which it points to.
If this Var is a function, when + is used in head position of a list,
clojure will try to call that function (NullPointerException if this Var happened not to point at a function). If supplied as an argument to
another function, that function may do the same to call it. That's
how function calling works.
further comments to round up:
Most or all languages use symbol tables. Being a somewhat dynamic language, Clojure uses this extra layer of indirection (Symbol → Var → function, rather than only Symbol → function) so that dynamically rewriting which function is tied to which symbol ― is more feasible and elegant, and this is sometimes a source of curiosity for beginners.
As other answers have somewhat overly emphasized, you may otherwise perform fancy stuff like quote it ('+) to avoid its evaluation, or even inspect it with class and/or resolve as if you are interested in verifying what it is (class), or which namespace it sits in (resolve). You can also poke at the var it points at via var or #'. You'll typically do those fancy things if you are writing macros or if you're very experimentally inclined, especially when working in the repl; depending on which style you write your macros, you might actually quote quite a lot in them.
and a fancy illustration for the extra-exploratory person:
Being a somewhat flexible language, clojure exposes api for taking the Symbol → Var → function walk on your own. You'd not typically ever do that for just using a function, because obviously that would be boring and redundant, but it can be used here to illustrate the process:
(deref (resolve '+))
Namely, the symbol is first resolved to its Var, then the thing that the Var points to, is arrived at. This just illustrates the 2-step process for arriving at a function (Symbol → Var → function), which happens behind the scenes. I hope you've avoided reading this extra part.
TL;DR
the answer to the original question is simply: Yes.
I find an understanding of the difference between symbols, functions, literals, and vars is necessary to grok what's happening.
(def one (fn [] 1)) ⇒ #'example/one. It references the function #function[example/one]
(def x one) ⇒ #'example/x references the function #function[example/one]
(def y 'one) ⇒ #'example/y references the symbol one
(def z #'one) ⇒ #'example/z references the var #'example/one
To put it precicely one is a symbol that resolves to the var #'example/one. The var references a function, #function[example/one], which returns the literal 1.
Each def yields a var. The var is denoted by the #' syntax in #'example/x. Each var references a value.
According to Clojure's own documentation, symbols resolve to a value, a special form, or an error when evaluated. So it can be a little confusing because there is no mention of a var:
(type one) ⇒ example$one
(type x) ⇒ example$one
(type y) ⇒ clojure.lang.Symbol
(type z) ⇒ clojure.lang.Var
In the cases above, the value "is the value of the binding of the global var named by the symbol." As another answer stated more succinctly: symbol → var → value.
(one) ⇒ 1
(x) ⇒ 1
(y) ⇒ unrelated associative lookup error
(z) ⇒ 1
Remember: #'example/z references the var #'example/one. #'example/x and #'example/y both reference #function[example/one]. The significance of this difference is revealed when the original symbol is interned to a new function: (def one (fn [] 2)).
(one) ⇒ 2 ← new value
(x) ⇒ 1 ← original value
(y) ⇒ unrelated associative lookup error
(z) ⇒ 2 ← new value
Following the logic of symbol → var → value:
x → (var x) → (defn one [] 1)
x resolves to (var x) ("the global var named by the symbol")
(var x) dereferences the current binding of x: (fn [] 1) ("the binding of the global var named by the symbol")
z → (var z) → (var one).
z resolves to its var, which dereferences to (var one)
one resolves to its var, which dereferences to (fn [] 2)
One final note. #'example/one still evaluates and returns a literal (1 or 2) because the var is in the first position of a list ((z)). This behavior is similar to placing a keyword in the first position of a list and a map in the second: (:two {:one 1 :two 2}) ⇒ 2.
call
(ns-map *ns*)
to get a map of all available symbols in your namespace and vars they are pointing to
Related
In Clojure,
(def x 3)
(eval '(prn x))
prints 3, whereas
(let [y 3]
(eval '(prn y)))
and
(binding [z 3] (eval '(prn z)))
generate an 'Unable to resolve var' exception.
According to http://clojure.org/evaluation, eval, load-string, etc generate temporary namespaces to evaluate their contents. Therefore, I'd expect neither of the above code samples to work, since (def x 3) is done in my current namespace, not the one created by eval.
Why does the first code sample work and not the last two?
How can I eval a form with bound variables without using def?
Thanks!
1.:
The reason this doesn't work is (more or less) given on the page you linked:
It is an error if there is no global var named by the symbol […]
And:
[…]
A lookup is done in the current namespace to see if there is a mapping
from the symbol to a var. If so, the
value is the value of the binding of
the var referred-to by the symbol.
It is an error.
eval evaluates forms in an empty (null in CL-lingo) lexical environment. This means, that you cannot access lexical variable bindings from the caller's scope. Also, binding creates new bindings for existing vars, which is why you cannot use it "by itself", without having declared or defed the variables you try to bind. Besides, lexical variables (at least in CL, but I would be surprised if this wasn't the case for Clojure) already ceased to exist at runtime – They are translated to addresses or values.
See also my older post about this topic.
2.:
So, you have to use dynamic variables. You can avoid the explicit def, but you still at least need to declare them (which defs var names without bindings):
user=> (declare ^:dynamic x)
#'user/x
user=> (binding [x 10] (eval '(prn x)))
10
nil
By the way: I suppose you know why you need eval, and that its use is considered evil when other solutions would be appropriate.
I'm always a bit confused about Symbols and Vars in Clojure.
For example, is it safe to say that + is a symbol which is used to denote a var, and this var points to a value which is a function that can add numbers?
So what happens, step by step when I just enter "+" in a REPL?
The symbol gets qualified to a namespace, in this case clojure.core
Then in some symbol table there is the information that + refers to a var
When this var is evaluated, the result is a function-value?
There's a symbol + that you can talk about by quoting it:
user=> '+
+
user=> (class '+)
clojure.lang.Symbol
user=> (resolve '+)
#'clojure.core/+
So it resolves to #'+, which is a Var:
user=> (class #'+)
clojure.lang.Var
The Var references the function object:
user=> (deref #'+)
#<core$_PLUS_ clojure.core$_PLUS_#55a7b0bf>
user=> ##'+
#<core$_PLUS_ clojure.core$_PLUS_#55a7b0bf>
(The # sign is just shorthand for deref.) Of course the usual way to get to the function is to not quote the symbol:
user=> +
#<core$_PLUS_ clojure.core$_PLUS_#55a7b0bf>
Note that lexical bindings are a different mechanism, and they can shadow Vars, but you can bypass them by referring to the Var explicitly:
user=> (let [+ -] [(+ 1 2) (##'+ 1 2)])
[-1 3]
In that last example the deref can even be left out:
user=> (let [+ -] [(+ 1 2) (#'+ 1 2)])
[-1 3]
This is because Var implements IFn (the interface for Clojure functions) by calling deref on itself, casting the result to IFn and delegating the function call to that.
The visibility mechanism used when you define private functions with defn- is based on metadata on the symbol. You can bypass it by referring directly to the Var, as above:
user=> (ns foo)
nil
foo=> (defn- private-function [] :secret)
#'foo/private-function
foo=> (in-ns 'user)
#<Namespace user>
user=> (foo/private-function)
java.lang.IllegalStateException: var: #'foo/private-function is not public (NO_SOURCE_FILE:36)
user=> (#'foo/private-function)
:secret
See the documentation for namespaces:
Namespaces are mappings from simple (unqualified) symbols to Vars and/or Classes. Vars can be interned in a namespace, using def or any of its variants, in which case they have a simple symbol for a name and a reference to their containing namespace, and the namespace maps that symbol to the same var. A namespace can also contain mappings from symbols to vars interned in other namespaces by using refer or use, or from symbols to Class objects by using import.
So basically your steps 1 and 2 are unified: the namespaces are the symbol tables.
And regarding step 3: I like the definition for variables that they're combinations of names of values. The symbol is the variable's name, and evaluating it will result in its value.
This answer is not very different from the other ones, it just doesn't assume you originally wish to learn several new functions and concepts just to understand what's going on:
+ is a symbol sitting in clojure.core which is by default accessible to your code.
When used in your code without any very advanced intents such as quoting it or finding out its class ― clojure will seek the Var which it points to.
If this Var is a function, when + is used in head position of a list,
clojure will try to call that function (NullPointerException if this Var happened not to point at a function). If supplied as an argument to
another function, that function may do the same to call it. That's
how function calling works.
further comments to round up:
Most or all languages use symbol tables. Being a somewhat dynamic language, Clojure uses this extra layer of indirection (Symbol → Var → function, rather than only Symbol → function) so that dynamically rewriting which function is tied to which symbol ― is more feasible and elegant, and this is sometimes a source of curiosity for beginners.
As other answers have somewhat overly emphasized, you may otherwise perform fancy stuff like quote it ('+) to avoid its evaluation, or even inspect it with class and/or resolve as if you are interested in verifying what it is (class), or which namespace it sits in (resolve). You can also poke at the var it points at via var or #'. You'll typically do those fancy things if you are writing macros or if you're very experimentally inclined, especially when working in the repl; depending on which style you write your macros, you might actually quote quite a lot in them.
and a fancy illustration for the extra-exploratory person:
Being a somewhat flexible language, clojure exposes api for taking the Symbol → Var → function walk on your own. You'd not typically ever do that for just using a function, because obviously that would be boring and redundant, but it can be used here to illustrate the process:
(deref (resolve '+))
Namely, the symbol is first resolved to its Var, then the thing that the Var points to, is arrived at. This just illustrates the 2-step process for arriving at a function (Symbol → Var → function), which happens behind the scenes. I hope you've avoided reading this extra part.
TL;DR
the answer to the original question is simply: Yes.
I find an understanding of the difference between symbols, functions, literals, and vars is necessary to grok what's happening.
(def one (fn [] 1)) ⇒ #'example/one. It references the function #function[example/one]
(def x one) ⇒ #'example/x references the function #function[example/one]
(def y 'one) ⇒ #'example/y references the symbol one
(def z #'one) ⇒ #'example/z references the var #'example/one
To put it precicely one is a symbol that resolves to the var #'example/one. The var references a function, #function[example/one], which returns the literal 1.
Each def yields a var. The var is denoted by the #' syntax in #'example/x. Each var references a value.
According to Clojure's own documentation, symbols resolve to a value, a special form, or an error when evaluated. So it can be a little confusing because there is no mention of a var:
(type one) ⇒ example$one
(type x) ⇒ example$one
(type y) ⇒ clojure.lang.Symbol
(type z) ⇒ clojure.lang.Var
In the cases above, the value "is the value of the binding of the global var named by the symbol." As another answer stated more succinctly: symbol → var → value.
(one) ⇒ 1
(x) ⇒ 1
(y) ⇒ unrelated associative lookup error
(z) ⇒ 1
Remember: #'example/z references the var #'example/one. #'example/x and #'example/y both reference #function[example/one]. The significance of this difference is revealed when the original symbol is interned to a new function: (def one (fn [] 2)).
(one) ⇒ 2 ← new value
(x) ⇒ 1 ← original value
(y) ⇒ unrelated associative lookup error
(z) ⇒ 2 ← new value
Following the logic of symbol → var → value:
x → (var x) → (defn one [] 1)
x resolves to (var x) ("the global var named by the symbol")
(var x) dereferences the current binding of x: (fn [] 1) ("the binding of the global var named by the symbol")
z → (var z) → (var one).
z resolves to its var, which dereferences to (var one)
one resolves to its var, which dereferences to (fn [] 2)
One final note. #'example/one still evaluates and returns a literal (1 or 2) because the var is in the first position of a list ((z)). This behavior is similar to placing a keyword in the first position of a list and a map in the second: (:two {:one 1 :two 2}) ⇒ 2.
call
(ns-map *ns*)
to get a map of all available symbols in your namespace and vars they are pointing to
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
The code below prints 10 as expected.
(def x 10)
(let [y 30] (eval (symbol "x")))
The code below generates an exception:
(let [y 20] (eval (symbol "y")))
Unable to resolve symbol: y in this context
which is expected (but confusing!). According to the documentation, symbols defined by let do not belong to any namespace and so can not be resolved through namespace mechanism.
So the question is: what should be an equivalent of function symbol for local variables.
Additionally:
I thought that Clojure compiler internally calls function symbol for each identifier to "intern" it, but as the example above shows it is not the case. Curious what the compiler is actually doing with the local identifiers. I assumed that when I enter x in REPL
x
is is essentially processed as this:
(deref (resolve (symbol "x")))
but again evidently it is not the case for local variables.
PS: Symbols in Clojure does not cover local variables.
All input to the clojure compiler is read, to form lists, symbols, keywords, numbers, and other readable data (eg. if you use a hash map literal, the compiler will get a hash map).
For example:
user=> (eval '(let [y 20] y))
20
In this case, we give the compiler a list starting with the symbol let (which resolves to a var macro wrapping a special form).
When you ask "what should be an equivalent of function symbol for local variables", my first thought is that you are misunderstanding what the function symbol is for. The following is equivalent to my initial example:
user=> (eval (list (symbol "let") [(symbol "y") 20] (symbol "y")))
20
symbol is only incidentally useful for getting a var from a string. In fact this usage is usually a hack, and a sign you are doing something wrong. Its primary purpose is to construct input for the compiler. Writing a form that gets a binding from its lexical scope is best done by writing a function, and having the user pass in the value to be used. History shows us that implicitly using locals in the callers environment is messy and error prone, and it is not a feature that Clojure explicitly supports (though there are definitely hacks that will work, which will be based on implementation details that are not guaranteed to behave properly the next release of the language).
Occasionally when looking at other people's Clojure code, I see a function defined via defn and then called using the var-quote syntax, e.g.:
user> (defn a [] 1)
#'user/a
user> (a) ; This is how you normally call a function
1
user> (#'a) ; This uses the var-quote syntax and produces the same result
1
For the life of me I can't figure out the difference between these two ways of calling a function. I can't find anything in the evaluation documentation to say what happens when the operator of a call is a var that might suggest why the second form would be preferred. They both seem to respond in the same to binding assignments and syntax-quoting.
So, can somebody please provide a code sample that will illustrate the difference between (a) and (#'a) above?
Edit: I know that var-quote can be used to get to a var that's shadowed by a let lexical binding, but that doesn't seem to be the case in the code that I'm looking at.
(#'a) always refers to the var a, while (a) can be shadowed by local bindings:
user> (defn a [] 1)
#'user/a
user> (let [a (fn [] "booh")] [(a) (#'a)])
["booh" 1]
But most actual uses of var-quote / function call are not calling the var-quote expression directly, but instead cache its value so that higher-order constructs refer to the current value of var a instead of its value when passed in:
(defn a [] 1)
(defn my-call [f] (fn [] (+ 1 (f))))
(def one (my-call a))
(def two (my-call #'a))
(defn a [] 2)
user> (one)
2
user> (two)
3
This is mostly useful for interactive development, where you're changing some function that gets wrapped in a bunch of other functions in other packages.
The second form allows you to circumvent the privacy restrictions that clojure puts in place.
So, for instance, if you develop a library with private functions, but want to test them from a separate namespace, you cannot refer to them directly. But you can get to them using the var quote syntax. It's very useful for this.
Privacy is clojure is, in essence, a form of automatic documentation, as opposed to the privacy you see in Java. You can get around it.
user> (defn- a [] 1)
#'user/a
user> (ns user2)
nil
user2> (user/a)
CompilerException java.lang.IllegalStateException: var: #'user/a is not public, compiling:(NO_SOURCE_PATH:1)
user2> (#'user/a)
1
user2>