211

Crafting Interpreters

Reading this book brought me a better understanding of "the expression problem" and the use of the visitor pattern as its solution. This led me to (finally) grok the use of Class _Heirarchy_ Inheritance[0] as a solution not requiring visitors. In Newspeak[1], classes can contain nested classes, so when you subclass a class, you inherit the nested classes as well. This blog post discusses the same feature affording Free Object Algebras [2].

[0] https://blog.bracha.org/primordialsoup.html?snapshot=Amplefo... [1]https://newspeaklanguage.org [2]https://blog.bracha.org/primordialsoup.html?snapshot=Amplefo...

4 hours agogoodthink

Simply my favorite programming text of all time.

13 minutes agowduquette

I just went through this book during the winter holidays. I just love the author's casual writing style and all the tiny jokes and puns they made.

I hope we get to see "Add a type checker to Lox" sequel

3 hours agoincognito124

I love this book! I do wish there was a new edition that updated the version of Java used in the tree-walk interpreter. There's been some additions to the language, like sealed classes and exhaustive switches, that could really benefit the implementation.

4 hours agopapercrane

It's a fun little exercise left to the reader to upgrade to current Java. It pretty much eliminates the need for his ad-hoc code generation tool.

4 hours agobbaron63

Been there, did that, very much enjoy the result.

18 minutes agowduquette
[deleted]
4 hours ago

One of the best resources for learning compiler design. The web version being free is incredibly generous.

15 hours agoNora23

Compiler doesn't match the title of the book.

5 hours agofuzztester

You should read the book! :)

an hour agoMe1000

I had started but not come to that point yet. Mea culpa.

an hour agofuzztester

I have bought the print version of this 3 seperate times to give as a gift, its excellent.

14 hours agoacedTrex

It's a great book, I bought the paper version first, but man it was too big and heavy for my liking, ended up buying a digital copy; much more practical for notes and search...

although I keep getting lost somewhere in the mountain :)

I also recommend munificent's other book about game programming patterns. Both are fun to read.

13 hours agokeyle

Sometimes I get the spine guillotined off and replaced with a ring binding. Any print shop can do it for you, and you just lose the gutter plus a little margin. Easier to work with at a desk, and you can even split into two "books" if you feel it necessary.

But that's only for books I don't want to keep, and Crafting Interpreters is definitely a keeper...

6 hours agoflir

Interesting idea. Thanks.

6 hours agokeyle

I've found this book to be a good way to learn a new language, because it forces you to do a bit of reading about various language features and patterns to create equivalent implementations. For languages that lack some of the features in Java, it can be tricky to learn how to apply similar patterns, but that's half the fun (for me).

14 hours agochrysoprace

Really I would love to know how parse context sensitive stuff like typedef which will have "switched" syntax for some tokens. Would like to know things like "hoisting" in C++, where you can you the class and struct after the code inside the function too, but I just find it hard to describe them in rigorous formal language and grammar.

Hacky solution for PEG such as adding a context stack requires careful management of the entry/exit point, but the more fundamental problem is that you still can't "switch" syntax, or you have to add all possible syntax combination depending on the numbers of such stacks. I believe persistent data structure and transactional data structure would help but I just couldn't find a formalism for that.

16 hours agostevefan1999

C/C++ has one of the worst-designed syntaxes, its such a shame that entire families of the most popular languages ended up copying the same mistakes.

I know it's no solace to you, but Rust and Go don't even have this problem Afaik, and it's avoidable by careful consideration.

3 hours agotorginus

Part of a 2nd half of this book translated to Go became a skeleton for the BCL configuration language https://github.com/wkhere/bcl

10 hours agokunley

I stopped reading when he started using the visitor pattern

9 hours agojokoon

The visitor pattern is very common in programming language implementations. I've seen it in the Rust compiler, in the Java Compiler, in the Go compiler and in the Roslyn C# compiler. Also used extensively in JetBrains' IDEs.

What do you have against this pattern? Or what is a better alternative?

5 hours agoceronman

Visitor is heavy of code pattern that can be replaced by elegant, readable switch with exhaustive check, so all operations available by "Kind" enum are covered.

4 hours agohigh_na_euv

This wasn't available in Javs at the time. You're free to rewrite it with pattern matching (like the book, quite literally, leaves as an exercise for the reader).

4 hours agowiseowise

A switch or pattern matching approach is useful, but not practical for some cases. For example, there are cases where you are interested in only a single kind of node in the three, for those cases the Visitor pattern is very helpful, while doing pattern matching is cumbersome because you have to match and check almost every node kind. That's why, for example, the Rust compiler still uses the visitor pattern for certain things, and pattern matching for others.

3 hours agoceronman

Roslyn has visitor pattern combined with the 'Kind' enumeration you mentioned. You can either choose to visiti a SyntaxNode of a certain type, or override the generic version and decide what you want to do based on that enumeration.

3 hours agotorginus

Exhaustive switch with tail-calling makes for a very fast and readable interpreter.

4 hours agowffurr
[deleted]
6 hours ago

What’s bad about the visitor pattern? /gen

7 hours agovolemo

https://grugbrain.dev/

grug very elated find big brain developer Bob Nystrom redeem the big brain tribe and write excellent book on recursive descent: Crafting Interpreters

book available online free, but grug highly recommend all interested grugs purchase book on general principle, provide much big brain advice and grug love book very much except visitor pattern (trap!)

Grug says bad.

In all seriousness, the rough argument is that it's a "big brain" way of thinking. It sounds great on paper, but is often times not the easiest machinery to have to manage when there are simpler options (e.g. just add a method).

4 hours agocfors

The bytecode interpreter in the second half of the book doesn't use the visitor pattern.

8 hours agokevthecoder

No, but his first "Tree-walk Interpreter" does - he builds an AST then uses the visitor pattern to interpret it.

https://craftinginterpreters.com/representing-code.html#work...

5 hours agoHarHarVeryFunny

To quote the very first paragraph of the bytecode interpreter section[1]:

> The style of interpretation it uses—walking the AST directly—is good enough for some real-world uses, but leaves a lot to be desired for a general-purpose scripting language.

Sometimes it's useful to teach progressively, using techniques that were used more often and aren't as much anymore, rather than firehosing a low-level bytecode at people.

[1] https://craftinginterpreters.com/a-bytecode-virtual-machine....

2 hours agoetyp

Sure, I'm not criticizing it.

He's doesn't actually build on this though, but rather goes back to a single pass compiler (no AST, no visitor) for his bytecode compiler.

2 hours agoHarHarVeryFunny

the parser does

7 hours agojokoon

The parsers in crafting interpreters do not use the visitor pattern. The visitor pattern is used when you already have a tree structure or similar. The parser is what gives you such tree structure, the AST. When you have this structure, you typically use the visitor pattern to process it for semantic analysis, code generation, etc.

5 hours agoceronman

I’ve only glanced at the second part but I don’t remember that being the case.

7 hours agotonyedgecombe

Why?

5 hours agofuzztester

In case anyone finds it useful, we (CodeCrafters) built a coding challenge as a companion to this book. The official repository for the book made this very easy to do since it has tests for each individual chapter.

Link: https://app.codecrafters.io/courses/interpreter/overview

16 hours agorohitpaulk

Not sure why this ad (access needs paid membership) is the top comment

10 hours agomi_lk

Crafting Interpreters is the one thing that LLM's can do really really well. Because it is so easy to define and test.

Here are is a new LUA interpreter implemented in Python:

https://github.com/rhulha/MoonPie

And here is a new language:

https://github.com/rhulha/EasyScript

9 hours agoraymond_goo

> Because it is so easy to define and test

Probably also because there 100+ implementations for it to copy from

8 hours agonicoburns

LLMs can write much better comments than you do, but for some reason you continue to write them. Why?

4 hours agowiseowise

What even is the point of that? The whole point of the book is to get a sense and mindset of crafting compilers.

7 hours agoramon156

Is MoonPie your project? Have you written up anything about your experience and process of creating it?