The Evaluator

Let's take those symbols we looked at before, but this time our reader will hand them off to the evaluator...

even? odd? + -

They are all pointing to functions! But we are not actually running them; we are merely displaying them. To make the evaluator invoke a function, we must surround it in parens and pass whatever arguments we wish...

(even? 7) (odd? 7) (+ 1 2) (- 3 2)

When there are nested function calls, the evaluator invokes them, starting with the inner-most ones:

(odd? (+ 1 (- 3 2)))

The evaluator found these functions by looking them up in a table behind the scenes. The association of a symbol to a globally-accessible value is called a var. You can make your own var using def:

(def my-name "Alice")

While the previous vars pointed to functions, this one points to a string. Vars can point to any kind of value. Now wherever we use my-name, the evaluator will look up the var and return its value:

my-name

Let's pass it as an argument to the first function and grab the first letter:

(first my-name)

The distinction between a symbol and a var is crucial to understand. After our reader parsed my-name, it was considered a symbol, and after handing it off to the evaluator, it found that it was a var and retrieved its value. Let's visualize the life of my-name...

text   ->   symbol   ->   var
     (read)        (eval)

If the evaluator can't find what a symbol is pointing to (for example, it was not defed anywhere), it will throw an error. However, there is a way to tell the evaluator to not try to resolve it:

'this-symbol-points-to-nothing

By putting a single quote before a symbol, we are short-circuiting the evaluator and simply telling Clojure to let it remain as a symbol. This is not a common thing to do, because the entire point of symbols is to point to values, but we'll find some use cases in the future. For now, just keep in mind that a single quote is a simple way to shut off the evaluator.

Previous: The ReaderNext: Vectors and Sets