Your first Clojure
What Clojure is, why the operation comes first, and the three ways a program says something out loud.
A Lisp that runs on the Java machine
Clojure is a Lisp, which means the code you write and the data you work with have the same shape: a list inside brackets, where the first item says what to do. It is a small language by design, and because it runs on the Java machine it can use everything Java already has — but none of that is needed today. A function call and a list of three numbers are the same kind of object, which is why a program can build code as easily as it builds data.
The Clojure in this page runs on a machine a couple of seconds away. Press Run and read the output. Every example prints its answers, and that output is the whole feedback you need. A value you never print is invisible: the pane shows what the program wrote, not what it worked out along the way.
The operation comes first
Most languages put the sign in the middle: 2 + 3. Clojure puts the operation first and everything it works on after it, all inside one pair of brackets: (+ 2 3). Read the opening bracket as "do this" and the rest follows. Addition, subtraction and division keep their usual signs; multiplication is a star. The first item is the operation and everything else is an argument, so (+ 1 2 3) is the same operation with a different count.
Nesting reads from the inside out, and the brackets decide what happens first, so there is no table of precedence to remember. A line that starts with a semicolon is a comment: the sandbox ignores it, and it is there for the next person reading the file. An operation handed the wrong number of arguments says so by name, which is usually the quickest clue that a bracket has moved.
Every form has a value
A Clojure file is not quite a list of instructions in the way a script in another language is. Each pair of brackets is a form, and a form is worked out to a value: (+ 1 2) becomes 3, and (println "hi") prints and then becomes nil. That value is what the next form can use.
That is why the last expression in a function is the answer, and why printing and computing are separate acts. println is useful for seeing a value, but it is not the value. A line that prints and a line that computes can look equally important and mean different things.
The file is read from top to bottom, one form at a time. A form can use a name made by an earlier form, never one made later, so the order of the lines is part of what the program says.
Reading the brackets
Count brackets in pairs, not lines. An opening bracket starts a form; its partner closes it. A form can sit inside another, and the inner one finishes first, which is the whole of the evaluation order.
When a line looks wrong, read from the innermost brackets outward. (+ 1 (* 2 3)) has one small form that becomes 6, and the outer form then adds 1. The brackets tell you what happens first, so there is no precedence table to remember.
Indentation is a reading aid rather than a rule: the runtime does not care where a line begins, but a person does. Line the arguments up under the operation and the shape of a long form becomes visible at a glance.
What the reader does before the evaluator
The first thing that happens to a file is reading, not running. The reader pairs the brackets, turns the text into forms, and only then hands them to the evaluator one at a time. A bracket problem is reported before a single line has run, while a wrong operation is reported at the form where it appears.
One call per line, and how a program prints
; Everything is a list, and the first item acts.
(println "Hello, Clojure!")
(println (+ 2 3))
(println (* 6 7))
(println (- 10 4))
; Nesting is worked out from the inside.
(println (+ 1 (* 2 3)))
; print does not end the line.
(print "side")
(print " by side")
(println)
; prn keeps the quotes on a string.
(prn "Ada")
(println "Ada")Run it, then change it
Press Run and read the output line by line. Then change 6 to 9, add a line that prints `(- 100 1)`, and write the two printed words with two spaces between them so you can see print keeping them on one line.
(println a b) writes its values with a space between them, then starts a new line. print leaves the cursor where it is, so the next thing continues on the same line, and (println) on its own writes just the line break. prn is the readable printer: same as println, but a string keeps its quotes.
Three things stop a first Clojure file. An opening bracket with no partner fails the whole file, and the message often points at the end rather than at the line where the bracket is missing. An operation written outside its brackets, as in (println 2 + 3), is not an error at all: it prints three values with spaces, which is worse because it looks deliberate. And a print with no println after it leaves the next line glued to it.
Try these next
- Print the result of
(- 100 1), then add a second call that prints the same value again. - Print a label with
printand its number withprintln, and check where the line breaks. - Add a comment with a semicolon, then remove it and confirm the output does not change.
A ticket printed in three parts
Run it and read the six lines. Then change the tea count and the cake price, and add a line that prints the change from 20 with `print` so the label and the number share a line.
Check what you learned
One question at a time. A wrong answer explains itself — take another go.
Part 1 of 5
How do you print the sum of 3 and 4?
