BTW, I'm not the author of either of those books, but I have read both of them.
(There are fewer options for the second half, since you need more control over memory management.)
Does it? I know it uses metaprogramming (a Java program that outputs another Java program), but that’s probably easier in other languages than in Java. In my Python implementation I was able to significantly simplify that part of the code by using `eval`.
I do remember him using the visitor pattern to implement part of the parser I think. I thought that was kind of an odd choice, especially since it seemed like he was really just trying to avoid Java boilerplate.
Regardless, the book is incredible, and the choice of Java to start with makes sense. Its probably going to be the most universally approachable for everyone, even if they aren't super familiar. C can be pretty overwhelming if you aren't familiar it.
It's used to allow writing a "resolver" and an "interpreter" that both know how to handle every type of node in the AST. It's almost a functional approach, and I actually think it might increase boilerplate because Java is more designed around the object-oriented approach of adding `resolve` and `interpret` methods directly to each node type.
The two approaches result in very different code organisation, though - maybe the visitor approach was easier to explain in prose.
I wonder if he wrote today if he would have used a Record and done the more straightforward implementation.
private void execute(Stmt statement) {
switch (statement) {
case Stmt.Expression expression -> evaluate(expression.expr());
case Stmt.Block block -> executeBlock(block.statements(),
new Environment(environment));
...
public sealed interface Expr permits
Expr.Assign,
Expr.Binary,
Expr.Call,
Expr.Function,
.... more exprs hereMost of the people I know who write Java would have an aneurysm at seeing a switch statement.
To be clear, that's a critique of the Java mindset, not your code. Lol
I thought his focus was Dart these days given being employed by Google.