Beau­ti­ful Racket / tuto­ri­als

Make a programming language in one hour: stacker

Let’s make stacker, a pro­gram­ming lan­guage that func­tions as a stack-based cal­cu­la­tor.

1
2
3
4
5
6
#lang reader br/demo/stacker
4
8
+
3
*

Our lan­guage main­tains a stack of argu­ments, which starts out empty. Each line of the pro­gram puts a new argu­ment on the stack. If it’s a num­ber, it’s sim­ply pushed onto the top of the stack. But if it’s an oper­a­tor — either + or * — the top two argu­ments from the stack are popped off, and replaced with the result of apply­ing the oper­a­tor (mean­ing arg1 + arg2 or arg1 * arg2). So this sam­ple pro­gram means 3 * (8 + 4), and when it runs, the result is:

1
36

The stack is imple­mented with a list, the basic data struc­ture of Racket. By con­ven­tion, the top of our stack will cor­re­spond to the left side of a Racket list. Let’s visu­al­ize how the stack changes after each instruc­tion, using the rules described above:

1
2
3
4
5
6
7
#lang reader br/demo/stacker
; (list)
4 ; (list 4)
8 ; (list 8 4)
+ ; (list + 8 4) => (list 12)
3 ; (list 3 12)
* ; (list * 3 12) => (list 36)
1
36 ; top value of (list 36)

Easy, right? (If this seems like a weird way to do math, it’s called Reverse Pol­ish Nota­tion and has a long his­tory in cal­cu­lat­ing machines.)

Though stacker is sim­ple, it will give us a gen­tle intro­duc­tion to Racket, includ­ing a tour of its lan­guage-mak­ing work­flow. Every lan­guage project will fol­low the same basic steps.

It will also get us think­ing about the idea of a “lit­tle lan­guage” made for a spe­cial­ized pur­pose — also known as a domain-spe­cific lan­guage or DSL. We can make gen­eral-pur­pose lan­guages with Racket (and, in a later chap­ter, we will). But lan­guages don’t have to do every­thing. DSLs are valu­able because they can be tai­lored to the prob­lem at hand.

Pre­req­ui­sites

← prev next →