In this book we will create a programming language together.

We'll start with 0 lines of code and end up with a fully working interpreter for the Monkey* programming language.

Step by step. From tokens to output. All code shown and included. Fully tested.

Buy eBook for $29 Buy paperback for $39

eBook includes PDF, ePub, Mobi (Kindle) and HTML. Read a free sample.

Buy this book to learn:

  • How to build an interpreter for a C-like programming language from scratch
  • What a lexer, a parser and an Abstract Syntax Tree (AST) are and how to build your own
  • What closures are and how and why they work
  • What the Pratt parsing technique and a recursive descent parser is
  • What others talk about when they talk about built-in data structures
  • What REPL stands for and how to build one

Why this book?

This is the book I wanted to have a year ago. This is the book I couldn't find. I wrote this book for you and me.

So why should you buy it? What's different about it, compared to other interpreter or compiler literature?

  • Working code is the focus. Code is not just found in the appendix. Code is the main focus of this book.
  • It's small! It has around 200 pages of which a great deal is readable, syntax-highlighted, working code.
  • The code presented in the book is easy to understand, easy to extend, easy to maintain.
  • No 3rd party libraries! You're not left wondering: "But how does tool X do that?" We won't use a tool X. We only use the Go standard library and write everything ourselves.
  • Tests! The interpreter we build in the book is fully tested! Sometimes in TDD style, sometimes with the tests written after. You can easily run the tests to experiment with the interpreter and make changes.

"If you don’t know how compilers work, then you don’t know how computers work. If you’re not 100% sure whether you know how compilers work, then you don’t know how they work."

"Start by writing an interpreter with me!"

Thorsten Ball, author of the book you're looking at

This book is for you if you…

  • learn by building and love to look under the hood
  • love programming and to program for the sake of learning and joy!
  • are interested in how your favorite, interpreted programming language works
  • never took a compiler course in college
  • want to get started with interpreters or compilers…
  • … but don't want to work through a theory-heavy, 800 pages, 4 pounds compiler book as a beginner
  • kept screaming "show me the code!" when reading about interpreters and compilers
  • always wanted to say: "Holy shit, I built a programming language!"

The Monkey Programming Language

In this book we'll create an interpreter for the Monkey programming language. Monkey is a language especially designed for this book. We will bring it to life by implementing its interpreter.

Monkey looks like this:

// Bind values to names with let-statements
let version = 1;
let name = "Monkey programming language";
let myArray = [1, 2, 3, 4, 5];
let coolBooleanLiteral = true;

// Use expressions to produce values
let awesomeValue = (10 / 2) * 5 + 30;
let arrayWithValues = [1 + 1, 2 * 2, 3];

Monkey also supports function literals and we can use them to bind a function to a name:

// Define a `fibonacci` function
let fibonacci = fn(x) {
  if (x == 0) {
    0                // Monkey supports implicit returning of values
  } else {
    if (x == 1) {
      return 1;      // ... and explicit return statements
    } else {
      fibonacci(x - 1) + fibonacci(x - 2); // Recursion! Yay!

The data types we're going to support in this book are booleans, strings, hashes, integers and arrays. We can combine them!

// Here is an array containing two hashes, that use strings as keys and integers
// and strings as values
let people = [{"name": "Anna", "age": 24}, {"name": "Bob", "age": 99}];

// Getting elements out of the data types is also supported.
// Here is how we can access array elements by using index expressions:
// => 5

// We can also access hash elements with index expressions:
let getName = fn(person) { person["name"]; };

// And here we access array elements and call a function with the element as
// argument:
getName(people[0]); // => "Anna"
getName(people[1]); // => "Bob"

That's not all though. Monkey has a few tricks up its sleeve. In Monkey functions are first-class citizens, they are treated like any other value. Thus we can use higher-order functions and pass functions around as values:

// Define the higher-order function `map`, that calls the given function `f`
// on each element in `arr` and returns an array of the produced values.
let map = fn(arr, f) {
  let iter = fn(arr, accumulated) {
    if (len(arr) == 0) {
    } else {
      iter(rest(arr), push(accumulated, f(first(arr))));

  iter(arr, []);

// Now let's take the `people` array and the `getName` function from above and
// use them with `map`.
map(people, getName); // => ["Anna", "Bob"]

And, of course, Monkey also supports closures:

// newGreeter returns a new function, that greets a `name` with the given
// `greeting`.
let newGreeter = fn(greeting) {
  // `puts` is a built-in function we add to the interpreter
  return fn(name) { puts(greeting + " " + name); }

// `hello` is a greeter function that says "Hello"
let hello = newGreeter("Hello");

// Calling it outputs the greeting:
hello("dear, future Reader!"); // => Hello dear, future Reader!

Yes! All of this works with the interpreter we build in the book!

So, to summarize: Monkey has a C-like syntax, supports variable bindings, prefix and infix operators, has first-class and higher-order functions, can handle closures with ease and has integers, booleans, arrays and hashes built-in.

Readers are saying...

"Compilers was the most surprisingly useful university course I ever took. Learning to write a parser and runtime for a toy language helps take away a lot of "magic" in various parts of computer science. I recommend any engineer who isn't familiar with lexers, parsers, and evaluators to read Thorsten's book."

Mitchell Hashimoto (@mitchellh)
Founder of HashiCorp

"Amazing book! Besides satisfying my curiosity with clear writing and code examples, the book inspired me to apply those skills to a new http testing tool I’m working on."

Felix Geisendörfer (@felixge)
Prolific Open Source Contributor, Creator of GoDrone, Node.js Core Alumni

"Great book. I loved it because everything is built by hand, so you get to think about all the details, and it does so in a gradual way, which is didactic. The implementation itself is also nice and simple 🙌"

Xavier Noria (@fxn)
Everlasting student, Rails Core Team, Ruby Hero, Freelance, Live lover

"I really enjoyed the modern, practical approach of this book. Diving into the world of interpreters, by getting your hands dirty right from the beginning."

Christian Bäuerlein (@fabrik42)
Developer, Organizer & Curator of MECHANICON

"This book demystifies and makes the topic of interpreters approachable and fun. Don't be surprised if you become a better Go programmer after working your way through it."

Johnny Boursiquot (@jboursiquot)
Go Programmer, @BaltimoreGolang Organizer, @GolangBridge Core Member

"Great writing and explanations. The practical focus of the book kept me coding for a week straight. Definitely the best book to get into the magical world of compilers and interpreters."

Arthur Tabatchnic (LinkedIn)
Senior Cloud Solutions Developer

"We use parsers and interpreters on a daily basis, just think of JavaScript and JSON. This book not only helped me to better understand how they work but will come in handy the next time I have to implement a parser for an obscure data format."

Robin Mehner (@rmehner)
Developer, Organizer of BerlinJS, Reject.JS & NodeCopter.

"This book clearly, and elegantly explains the different pieces needed to make a language. From lexing and parsing to actually executing the code, this book does a great job explaining to the reader the purpose of each element and how they interact."

Lee Keitel (lfkeitel)
Systems Programmer & Network Technician

"Thorsten took a topic that is usually very dry and CS heavy and made it accessible and easy to understand. After reading this book I felt confident enough to write Plush, the templating language I’ve always wanted in Go! If you have yet to read Thorsten's book, I can't recommend it enough. Please go and buy it!"

Mark Bates (@markbates)
Creator of

Buy the eBook and you will get:

  • The complete book in ePub (iBook), Mobi (Kindle), PDF and HTML.
  • The complete, working interpreter for the Monkey programming language!
  • All the code presented in the book, easily usable, organized by chapters, MIT licensed and including the complete test suite.
  • Free updates: Once you buy the book you will get free updates for the lifetime of that edition of the book.
  • Money-Back-Guarantee: I want you to enjoy this book. If you, for any reason, are not happy with it just send me an email. You'll keep what you bought and your money back.

Buy the paperback and you will get:

  • The physical 260 pages paperback book
  • The complete, working interpreter for the Monkey programming language!
  • All the code presented in the book, easily usable, organized by chapters, MIT licensed and including the complete test suite.
  • Amazon Support: the book is distributed through Amazon and you get to benefit by all the money-back-guarantees and shipping Amazon offers.


  • Do I need previous experience with interpreters or compilers?

    Absolutely not! On the contrary, this book was written for you!

  • Can I read the book even though I'm not a Go programmer?

    Yes! I wrote the book with the aim to keep the code as easy to understand as possible. If you are experienced in other programming languages you should be able to understand it. Take a look at the free excerpt - that's as advanced as the Go code gets.

  • Why isn't the book called "Writing An Interpreter In Golang"? Wouldn't that be better for SEO?

    Well, I always thought I could use the "Golang" somewhere on the landingpage, maybe in the FAQ or something.

NEW The Lost Chapter: A Macro System For Monkey

More than half a year after publishing Writing An Interpreter In Go I decided to write another chapter. An additional chapter that's available to everyone: free to read online or to download as an eBook.

It's called The Lost Chapter: A Macro System For Monkey and can be thought of as the fifth chapter for Writing An Interpreter In Go. It builds directly upon the previous four and extends the Monkey interpreter as it stands at the end of the book.

In the chapter we add a fully-working Lisp-style macro system to Monkey, that's close to the way Elixir's macro system works. It looks like this:

let unless = macro(condition, consequence, alternative) {
  quote(if (!(unquote(condition))) {
  } else {

unless(10 > 5, puts("not greater"), puts("greater"));
// outputs only: "greater"

Building your own programming language is likely not something you do in your day job. But adding a fully working macro system? Well, that's not just unlikely, but outright bizarre and, oh, so much fun! Macros are code that that writes code. Can you imagine how much fun it is to write code that allows us to write code that writes code? Exactly!

About the author

Hi, my name is Thorsten Ball. I'm a programmer living in Germany. My whole professional life as a software developer I've been working with web technologies and have deployed Ruby, JavaScript, Go and even C code to production systems.

Maybe you've read one of my blog posts. Some of them are pretty popular. There's the one about the Ruby Garbage Collector. And the one about the fork system call. If you haven't read one of them, then maybe the one about forking processes in a multi-threaded environment.

I also give talks about Unix software and other topics. And I turned one talk into a blog post which got super popular and remains my favorite.

Writing an interpreter from scratch in Go has been one of the most enjoyable and fun things I ever did as a programmer. So I hope you enjoy this book as much as I enjoyed writing it.

If you want to know more about me, you can also visit my blog and website, check out my GitHub profile or even better: follow @thorstenball on Twitter.

Any questions?

If you have any questions, send me an email. I promise, you'll make my day. I love getting email from you: me @