Scheme from the ground up

Your first Scheme

What Scheme is, why the operation comes first, and the two ways to write something out: print and display.

Part 1 of 12

Beginner14 min readBack to Courses

A language where the brackets do the work

Scheme is one of the oldest languages still in daily use, and one of the smallest. The whole grammar fits on a postcard: everything is a list inside brackets, and the first item in the list is the thing to do. That single rule is why Scheme is still taught — nothing in the spelling gets between you and the idea.

The Scheme in this page is the real language, running in your browser. There is no compile step and no download to wait for: press Run and read the output. Every example prints its answers, and that output is the only feedback you need.

The operation comes first

In most languages a sum is written with the sign in the middle. Scheme puts the operation first and the arguments 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 are spelled with their usual signs; multiplication is a star. The only new habit is that the operation comes before the numbers it works on.

Nesting reads from the inside out: the innermost brackets are worked out first, and their answer is handed outward. There is no order-of-operations puzzle to solve, because the brackets already said what happens first. A line that starts with a semicolon is a comment, and the sandbox ignores it.

Reading a line out loud

To read a call, start at the opening bracket and name the operation, then take the arguments in order. (+ 1 (* 2 3)) says add one to the product of two and three; the inner call is a single argument, not two.

That is why prefix notation never needs a precedence table. * and + have no rank to memorise, because every grouping is already visible. When a line confuses you, put a finger on each opening bracket and match it with its closing one.

A file is read from top to bottom, and each form is evaluated in turn. Definitions have to appear before the line that uses them, so a program reads like a recipe rather than a set of declarations.

Two kinds of answer

Some calls answer a value and some only act. (+ 2 3) answers 5; (display "hi") writes text and answers nothing you should rely on. Wrapping a sum in print shows the value, while leaving it bare lets the interpreter move on.

That is why a program full of bare arithmetic prints nothing at all. The outermost call decides what happens to the answer, and only the printing calls put it on the screen.

Nested calls pass their answer inward, so the shape of the brackets is also the order of work. Once you can see that, a long expression becomes a sequence of small steps rather than one thing to decode.

Arithmetic, and two ways to print

; Every program is a list of lists.
(print (+ 2 3))
(print (- 10 4))
(print (* 6 7))
(print (/ 10 4))
(print (quotient 10 4))

; Nesting reads from the inside out.
(print (+ 1 (* 2 3)))

; print ends the line. display does not.
(display "one ")
(display "two")
(newline)

Brackets are the shape of the work

A pair of brackets is one call, not a decoration around one. That is why (+ 2 3) and (+ 2 3 4) are both legal: the operation takes as many arguments as you give it, and the brackets say where the call ends. Once you see brackets as the boundary of a call, a long line stops looking like punctuation and starts looking like a diagram.

Matching them is a skill worth practising deliberately. Count an opening bracket as one step in and a closing one as one step out; the line is balanced when the count returns to zero at the end. A missing closing bracket swallows the rest of the file, which is why the error often names the last line rather than the broken one.

Three mistakes account for most first sessions. A missing closing bracket makes the rest of the file disappear into one unfinished call. Writing (3 + 4) puts a number where an operation belongs. And (/ 10 4) gives 2.5 while quotient gives 2, so choose the one you meant.

Try these next

  • Print (- 100 (* 7 9)) and work out the answer before you run it.
  • Write a line that prints the remainder of 17 divided by 5 with remainder.
  • Use two display calls and one newline to put three words on one line.

Run it, then make it yours

Press Run and read the output one line at a time. Then change 6 to 9, add a line that prints `(- 100 1)`, and put a space between the two words the display calls write.

Output
Click "Run" to execute your code

Change, counted out

Run it and read how many dollars and cents are in 137. Then change the amount to 250, and add a line that prints how many whole quarters the cents would make.

Output
Click "Run" to execute your code

(display x) writes a value and leaves the cursor where it is, so the next thing continues on the same line. (print x) is display plus a line break, and (write x) is the raw form, where a string keeps its quotes. Reach for (newline) when you want a break after display.

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?