Yes, var is like a C pointer. This is poorly documented.
Suppose you define fred as follows:
(defn fred [x] (+ x 1))
There are actually three things. Firstly, fred is a symbol. There is a difference between the fred character (without quotes) and the keyword :fred (marked with a leading : char) and the string "fred" (marked with a double quote at both ends). For Clojure, each of them consists of 4 characters; that is, neither the colon of the keyword, nor the double quotation marks of the string are included in their length or composition:
> (name 'fred) "fred" > (name :fred) "fred" > (name "fred") "fred"
The only difference is how they are interpreted. The string is intended to represent user data of any type. The keyword is intended to represent control information for the program in readable form (unlike "magic numbers" such as 1 = left, 2 = right, we just use the keywords :left and :right .
The symbol should point to things like Java or C. If we say
(let [x 1 y (+ x 1) ] (println y)) ;=> 2
then x indicates the value 1, y indicates the value 2, and we see that the result is printed.
form (def ...) introduces an invisible third element, var . Therefore, if we say
(def wilma 3)
Now we have 3 objects. wilma is a character that points to a var , which in turn points to a value of 3 . When our program encounters a wilma character, it evaluates to find var . Similarly, var is evaluated to get a value of 3. Thus, this is similar to the bi-directional orientation of pointers in C. Since both characters and , var are "auto" evaluated, this happens automatically and invisibly, and you donโt need to think about var (really , most people do not know that an invisible middle step even exists).
For our fred function above, a similar situation exists, except that var points to an anonymous function (fn [x] (+ x 1)) instead of 3 as wilma .
We can short-circuit the automatic evaluation of var as:
> (var wilma) #'clj.core/wilma
or
>
where the reader macro #' (the pound quote) is a shorthand way to invoke a special form (var ...) . Keep in mind that a special form like var is an inline compiler, such as "if" or "def", and is not a regular function. The special form var returns a var object attached to the wilma symbol. clojure REPL prints the var object using the same shorthand, so both results look the same.
Once we have a var object, automatic evaluation is disabled:
> (println (var wilma)) #'clj.core/wilma
If we want to get the value that wilma indicates, we need to use var-get :
> (var-get (var wilma)) 3 > (var-get #'wilma) 3
The same thing works for fred:
> (var-get #'fred) #object[clj.core$fred 0x599adf07 " clj.core$fred@599adf07 "] > (var-get (var fred)) #object[clj.core$fred 0x599adf07 " clj.core$fred@599adf07 "]
where the material #object[clj.core$fred ...] is a clojure way of representing a function object as a string.
As for the web server, can it tell via the var? function var? or else, if the supplied value is a handler function, or var that points to a handler function.
If you type something like:
(jetty/run-jetty handler)
double automatic evaluation will give an object of the handler function, which is passed to run-jetty . If instead you enter:
(jetty/run-jetty (var handler))
then var , which points to the handler function object, will be passed to run-jetty . Then run-jetty will have to use an if or equivalent to determine what it got and call (var-get ...) if it got var instead of a function. Thus, each time through (var-get ...) object to which var is currently pointing will be returned. Thus, var acts like a global pointer in C or a global "reference" variable in Java.
If you pass an object to a run-jetty , it saves a "local pointer" to the function object, and there is no way for the outside world to change what the local pointer refers to.
Here you can find more information: