Parens vs Brackets in Clojure
From OO to Clojure Workshop!
Watch my free workshop to help you learn Clojure faster and shift your paradigm to functional.
Summary: Clojure uses both parentheses and square brackets as part of its syntax. It might at first appear to be arbitrary, but it's actually systematic. What's more, it reveals one of the coolest things about Clojure: expressions define how they interpret their arguments.
The other day someone asked me a very good question about Clojure. She
was learning the syntax and was wondering what the significance was
between parentheses and square brackets. She knew that square brackets
can also make a vector. What she
really wanted to know what in the more syntactic elements, like the
square brackets in a
fn, why did you use parens sometimes
and brackets other times?
The answer is simple: parens are for enclosing function calls or macro
calls, while the square brackets inside are data for the macro to
use. For instance, in the following
let form, the parens define the
lexical scope of the bindings while the bindings themselves are in
(let [x 1 y 2 z 3] (* z (+ x y)))
here, parens mean "start a
binding form gets meaning from
bindings in square brackets
parens because body of
let is more calls
Notice the body
(* z ...) is again in parens because it's function
In the following
defn, we have the parens defining the whole form
while the brackets define the data the function definition needs, namely
the argument names.
(defn fib [x] (cond (= 0 x) 1 (= 1 x) 1 :else (+ (fib (- x 1)) (fib (- x 2)))))
start a "defn" expression
agument list gets meaning from
body is more parens
Finally, we can see that brackets also mean "create a vector" in this expression:
(defn pair "Create a pair from the two arguments." [a b] [a b])
pair is interpreted as name of function
a string after the name is interpreted as the docstring
these are the arguments
everything else is the body; make and return a vector
The first element of an expression is used to determine how to interpret the rest. Clojure is basically interpreters (and compilers) all the way down. It's one of the coolest things about Lisps. From the get-go, they're defined in terms of themselves, recursively. If you'd like to learn Clojure, join the PurelyFunctional.tv Online Mentoring program. It's an exploration in interactive instruction. When you join, you set the topics, you get help where you need it, to become a Clojure professional.