Monkey logo

Monkey

The programming language that lives in books

What is Monkey?

Monkey is a programming language that you can build yourself by reading through Writing An Interpreter In Go and Writing A Compiler In Go.

There is no official implementation of Monkey — it lives in these books and it’s up to you, the reader, to implement it. First as a tree-walking interpreter, then as a bytecode compiler and virtual machine.

Here is what Monkey looks like:

// Integers & arithmetic expressions...
let version = 1 + (50 / 2) - (8 * 3);

// ... and strings
let name = "The Monkey programming language";

// ... booleans
let isMonkeyFastNow = true;

// ... arrays & hash maps
let people = [{"name": "Anna", "age": 24}, {"name": "Bob", "age": 99}];

It also has functions!

// User-defined functions...
let getName = fn(person) { person["name"]; };
getName(people[0]); // => "Anna"
getName(people[1]); // => "Bob"

// and built-in functions
puts(len(people))  // prints: 2

And it has conditionals, implicit and explicit returns and recursive functions, which means we can do this in Monkey:

let fibonacci = fn(x) {
  if (x == 0) {
    0
  } else {
    if (x == 1) {
      return 1;
    } else {
      fibonacci(x - 1) + fibonacci(x - 2);
    }
  }
};

But the crown jewel in every Monkey implementation are closures:

// `newAdder` returns a closure that makes use of the free variables `a` and `b`:
let newAdder = fn(a, b) {
    fn(c) { a + b + c };
};
// This constructs a new `adder` function:
let adder = newAdder(1, 2);

adder(8); // => 11

The Monkey Canon

Cover for Writing An Interpreter In Go Writing An Interpreter In Go was published in 2016, its latest version (1.6) was released in 2019.

The first book in the Monkey Canon defines the syntax of Monkey and describes its implementation as a tree-walking interpreter with the following features:

  • Integers, booleans, strings, arrays, hash maps
  • A REPL
  • Arithmetic expressions
  • Let statements
  • First-class and higher-order functions
  • Built-in functions
  • Recursion
  • Closures

Cover for The Lost Chapter The Lost Chapter: A Macro System For Monkey was published in 2017 as a free (to read online or download) addition to Writing An Interpreter In Go.

It can be thought of as Writing An Interpreter In Go's fifth chapter, since builds directly upon the previous four chapters and extends the Monkey interpreter as it stands at the end of the book.

The Lost Chapter: A Macro System For Monkey adds a fully-working Lisp-style macro system to Monkey, that's close to the way Elixir's macro system works.

Cover for Writing A Compiler In Go Writing A Compiler In Go was published in 2018 and its latest version (1.1) in came out in 2019.

This book is the sequel to Writing An Interpreter In Go and while it does not change its syntax and does not add any features, it changes the implementation of Monkey from a tree-walking interpreter into a bytecode compiler and virtual machine.

At the end of the book, Monkey looks and behaves exactly as it did at the end of Writing An Interpreter In Go, except that it's 3x faster!

Monkeys In The Wild

Some readers love to take little detours when following along with the books: a different implementation language, new features, a little twist on the syntax.

And since the code that’s presented in the books is MIT licensed, everybody’s free to turn their Monkey implementation into whatever their imagination comes up with and showcase it to the rest of the world.

Collected here are some of those interesting and cool Monkey implementations readers have shared with me.

Did you also built your own version of Monkey? Let me know, just send me an email to: me @ thorstenball.com


  • An implementation of Monkey in Elixir

  • Rust implementation of Monkey programming language from the book Writing an Interpreter in Go. This interpreter is also compiled into WebAssembly format so it can run on browser.

  • Mico (“Monkey” in catalan). Monkey language implementation done with C++. Including a ton of extensions:

    • Modules
    • Mutability
    • For-loops
    • Intervals

  • A step-by-step walk-through where each commit is a fully working part.

  • A complete Monkey implementation in Typescript

  • A full Monkey implementation of the bytecode compiler and VM from Writing A Compiler In Go in C#

  • A fully working interpreter for the Monkey programming language as known from the book Writing an Interpreter in Go, written in Dart.

  • Monkey programming language written in Rust. Including compilation to WASM and an online playground

  • This repository started life as the implementation written by gaufung, but it has now diverged significantly in terms of both features and implementation. Including:

    • File I/O
    • A standard library
    • Postfix operators
    • Function argument defaults

  • A Monkey implementation in ISO C11 with additional features:

    • The % modulo operator
    • The logical && and || operators
    • While-loops
    • A built-in type() function to determine the type of a Monkey value

  • This repository contains a C# port of the Monkey programming language from the Writing an interpreter in Go book. Its code closely resembles that presented in the book, but written in idiomatic C# for the .NET Core runtime. Using the instructions below, the interpreter runs on both Windows, Mac, and Linux.

  • The geo programming language based on Monkey.

    Special features:

    • All functions are curried
    • Scopes lives on blocks, no name clashes
    • Pipe operator: the result of one expression becomes the last argument on a subsequent function call expression
    • Unicode support
Copyright © 2019 Thorsten Ball. All rights reserved.