Crafting Interpreters – Nystrom

I have read this book, went through the exercises and went back to reference this book a number of times.
It’s 10/10 excellent
but I confess I almost forgot to write a review as I mostly read it online and only bought the (heavy book. See pic) to make sure the author got paid for his brilliant work.

Summary: “A comprehensive introduction to writing an interpreter for a dynamically typed, object-oriented toy programming language (Lox). Throughout the book the author develops two complete interpreters for the language from start to finish, including all the front-end and backend parts. The first is a simple AST walking interpreter implemented in Java, and the second is a moderately optimized VM written in C, including a garbage collector.” (src)

Crafting Interpreters Book

Batteries Included = Comes together with all possible parts required for full usability

Every developer should:

  1. Implement a programming language at least once.
  2. Use this book as a guide.

I confess I didn’t arrive at this book naively. I have previously taken 1 university course on compilers and implemented parts of a language naively, i.e. just having a go without any advance thought. If possible I would recommend “having a go” first as it will truly make you appreciate how great this book is.

Robert Nystrom gently leads you down the garden path of creating an interpreter in java and then in C. Even with no C/java experience I think most people could follow along. In fact a major positive of the book is that all code is covered in the book. In theory and mostly in practice I did this. I implemented the language as I followed the book. I wasn’t making his lox language but every step he showed was applicable and useful.

Since I’ve been writing a language on/off for a few years and recently stumbled upon the book. I’ve been particularly interested to read the parts of the book I’ve already implemented to see how someone else approached or thinks about the problem. It has been highly amusing, Robert has some keen insights and his diagrams are brilliant!

If you are a programmer buy this book and more importantly follow it to implement a language that interests you.
The insight it will give you long term is invaluable.

Link to referenced summary:

Bonus Points: +1 for the author as I emailed them in 2020 when I read the book and they gave a detailed reply to a particularly niche query. Thanks Bob.

The Understated Simplicity of Good Code

Bad Code Accretes

Sometimes while reading code, I get the impression that the person:

  1. Kept throwing more code at the problem until it “worked”.
  2. They never for a moment stepped back and thought about making it simpler.

This small thought can then be applied on a larger scale to languages themselves. PHP was quickly thrown out there at version 1 and early on added to as new features were needed. Java/C#/javascript almost all of them have grown by adding features over time. How many have went back and removed significant features?

Great Code Simplifies

Contrast that approach to Ken Iverson in this video from 1974:


I went from application to application trying to use the same techniques. The most encouraging thing is that they would work. After 2-3 years during which time the language had grown by accretion, it grew and grew, eventually I found it was shrinking.

Essentially the idea was once you look at enough different applications you begin to see what is the general notion. So I came to generalisations that allowed me to take out whole chunks of special things I had put in.

Furthermore to my surprise it turns out the general ideas are usually much simpler to understand than any of the special cases.

Modern Languages are Simplifying Common Cases

Looking at some of the recent changes for example arrow-operators in javascript, records/lambdas in java you can see this attempt to go back and simplify and reduce the noise for getting common actions performed. The questions is will many remove the old noise.

An Example from KDB

I find it worth mentioning how KDB supplies the user with handles to send data. Here we open a handle h to send a query to a remote process and get the result.

q)h:hopen `:localhost:5000;
q)h "2+2"

That last line shows that the handle is 7. Why is KDB using 7 for handles?
Because linux maps files/sockets etc. using those exact same integers. In fact in kdb standard out/error can be used as 0/1. When people first encounter this, they find it confusing, possibly because they are coming from other languages that wrap handles ten layers deep in abstractions. I can’t help but imagine:

  • Some coders take hours to work out what code can be removed
  • Other developers like Arthur may never consider introducing unnecessary abstractions in the first place


Please for the sake of your reviewers take a moment before pushing code to ask yourself, can this be made simpler.