tl;dr - "Crafting Interpreters" by Robert Nystrom is an excellent inspirational read about a topic an average software engineer (like me) doesn't have to deal with every day.
The book left me with the urge to tell you about it, so here we are - and to invent yet another programming language which is just stupid given the many languages out there and my limited time at hand - but still...
See for yourself: https://craftinginterpreters.com
Read on if you want to get to know more about this gem.
Software engineering is a broad area and ever-evolving. Working in this field, my day-to-day job covers only a tiny slice of topics therein. Which I believe is true for most software engineers out there.
Now and then, I feel the urge to explore topics outside of my technology-wise comfort zone. Mainly stuff I got in contact with way back during my CS classes, knowledge almost buried and lost in my nebulous wetware.
Reading "Crafting Interpreters" by Robert Nystrom was one of those excursions. When I got hold of this book, it was a permanent companion during my summer vacation. I love it, and here is why.
Building compilers was one of my favourite classes back then, despite my choice to deepen my studies in computer graphics later.
Building interpreters, compilers, or other tooling around programming languages is widely perceived as black art. However, the author's relaxed and engaging writing style makes the book impressively accessible to anyone with basic programming skills, despite its depth and details.
The common thread of this book is to have you written a complete interpreter by the end.
I believe that is a novum amongst other literature in this field, mainly focusing on theoretical concepts. "Crafting Interpreters" lets you code along, building an interpreter for Lox, a dynamically typed language with first-class functions and basic object-oriented features if you want.
In fact, it does it twice. The first part walks you through the implementation of both the interpreter and virtual machine in Java - kind of as a warm-up, giving you the general concepts and ideas. The second and bigger part of the book re-implements the whole shebang in just C with a focus on performance, without all the conveniences a higher-level language brings, for example, data structures (linked lists, hash tables) or memory management behind the scenes (garbage collection).
The second part of the book reminded me that there is software out there that is not bottlenecked by unnecessary DB roundtrips or chatty service contracts when we look at performance - things I often have to deal with in my job.
When building an interpreter for a programming language and the virtual machine executing the users' programs, you create a piece of software that runs solely in-process, where performance degrades mainly through poor algorithms and data structures. Something you wouldn't start investigating when expensive database queries are the limiting factor or remote procedure calls define the performance baseline.
I found it very refreshing to see optimisations, like the clever use of bit manipulations, e.g. in the case you need to compute the modulo of a number which always happens to be a power of 2, or taking data locality into account, or the cost of pointer indirections.
The book has a lasting effect on me as I sometimes see myself (pointlessly) wondering if the data used in the hot code path I just wrote fits nicely into a cache line or has to be fetched slowly from RAM.
The book is beautifully typeset and illustrated. You can feel the love and passion Robert Nystrom has put into this work. In that regard, it is way above most other software engineering books I have read. I could imagine that even readers who are not so much interested in the topics explained would skim through the book and then suddenly find themselves start reading it.
There are no serious downsides, in my opinion. And those mentioned below didn't bother me greatly.
Implementing an interpreter is one thing. Ensuring it behaves along a programming language's semantics is another. Unfortunately, the aspect of testing is skipped altogether, something you'd have to deal with when inventing a real language beyond toy purposes.
Additionally, and primarily due to the nature of the book carrying the complete implementation in its pages, there are some boring passages regarding programming chores like header files, includes and imports.
A refreshing book if you're interested in the inner workings of interpreters or if you need some brain stimuli.
Thanks, Robert Nystrom, for this book and the many inspirations within! ❤️
Dear readers, I'd love to hear in the comments about books which impressed you lately! 👋