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)
Batteries Included = Comes together with all possible parts required for full usability
Every developer should:
Implement a programming language at least once.
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.
Developers, Code Cowboys and Architecture Astronauts.
Slums, Skyscrapers and Ghost Cities.
Similar to constructing buildings, there are (at least) three approaches to software development:
Coders = Slums – Quickly built using material and knowledge at hand to develop for a small audience quickly. Good ideas will be copy-pasted from one area to another and modified to suit the individuals needs. We can cover a lot of ground quickly but it doesn’t scale, plumbing and electricity break down.
Developers = Skyscrapers – Construction takes longer, the outcome can result in a uniformity, often piecing together existing architectural concepts or libraries into a fairly standard shape. We can scale to a higher level (density of people) but we need more upfront planning and less individuality.
Architecture Astronauts = Ghost Cities = Master architects devise grand schemes of hugely scaleable systems but there are fundamental flaws in the plan and often the need of actual end users are ignored.
If this conceptual metaphor holds, what could we learn from the building industry?
Don’t employ a coder when you need an architect?
Sometimes you need to clear a slum, displeasing those residents to replace it with an efficient residential building, which will take time and investment?
Building quality needs enforced by external parties?
Similar to governmental building inspections.
Always get the core plumbing right, the facade/paint can be changed later?
Is there anything they could learn from software development?
Perhaps the most important thing is to decide which category you are aiming for.
Sometimes while reading code, I get the impression that the person:
Kept throwing more code at the problem until it “worked”.
They never for a moment stepped back and thought about making it simpler.
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
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.
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.