3 Basic constructs

 

This chapter groups together some of the most important constructs in Clojure (and similarly other programming languages): conditional branching, iteration and local scope definition. There are other aspects that could be added to this category like namespaces, variables or functions, but because of their complexity they are treated separately.

You might be surprised to see things like conditionals, switch statements or loops as being part of the standard library. But Clojure (as many other Lisps before) builds up from a small core of primitives called special forms and many constructs that would be considered "reserved words" in other languages are instead defined in the standard library. This is why the Clojure standard library could be considered also a language specification.

The book treats special forms, macros and functions equally, provided they are publicly available for use after Clojure bootstrap. Some of them however, are meant for Clojure internal use and just mentioned briefly.

3.1 Lexical Binding

Lexical binding is a mechanism to create an accessibility boundary for values. The mechanism works by assigning values to symbols in the scope defined by surrounding parenthesis (hence why it’s called "lexical"). The following picture for example, shows what boundaries are created by the let macro:

Figure 3.1. Lexical scope for locally bound symbol "b".
06 lexical scope

3.1.1 let and let*

3.1.2 if-let, when-let, if-some and when-some

3.1.3 letfn and letfn*

3.2 Boolean and Bitwise Operators

3.2.1 not

3.2.2 and, or

3.2.3 bit-and and bit-or

3.3 Conditional Branching

3.3.1 if, if-not, when and when-not

3.3.2 cond

3.3.3 condp

3.3.4 case

3.4 Iteration and loops

3.4.1 loop, recur and loop*

3.4.2 range