23 Dynamic variables in the standard library

 

This chapter describes the dynamic variables available in the Clojure standard library. Some of them already appeared in the book, but others still deserve a more detailed explanation which is the subject of this chapter. One of the main use of dynamic variables is as communication channel across the call stack: by wrapping a function call in a binding form for example, all subsequent invocations will be able to read and use dynamic values. Dynamic variables are used extensively inside Clojure itself to expose configuration options for different features: the reader, the compiler, the printing system and much more. Some dynamic variables have been grouped into a single section when they are intimately correlated or part of the same sub-system.

23.1 *1, *2, *3 and *e

Dynamic variable names are conventionally surrounded by a pair of asterisks (colloquially known as "earmuffs"), but *1, *2, *3 and *e are an exception. One possible reason is that they are meant to be read-only and for internal use of the Clojure REPL only:

  • *1 stores the result of the previous evaluation, if available.
  • *2 stores the result of the evaluation before *1.
  • *3 stores the result of the evaluation before *2.
  • *e stores the exception object if the previous evaluation resulted in an error.

For example, let’s have a look at the following REPL session:

user=> (+ 1 1)
2
user=> (+ 2 2)
4
user=> (+ 3 3)
6
user=> [*1 *2 *3] ; #1
[6 4 2]

23.2 *in*, *out* and *err*

23.3 *agent*

23.4 *assert*

23.5 *clojure-version* and *command-line-args*

23.6 *compile-files*

23.7 *compile-path*

23.8 *compiler-options*

23.9 *file* and *source-path*

23.10 *use-context-classloader*

23.11 *allow-unresolved-vars*

23.12 *read-eval* and *suppress-read*

23.18 *math-context*