|
A friend of mine recommended the book "Crafting Interpreters" by Robert Nystrom. I've seen reviews calling it one of the best programming books of the last 10 years.
I have read it and it is an excellent book, and I recommend it for further study after this course. The author walks you through building an interpreter for an object oriented language called "Lox" (Lox has operator precedence, dynamic types, garbage collection, closures, classes, inheritance), and you build it line by line in Java (where the interpreter walks an abstract syntax tree), and then you do it again in C (the C version compiles to bytecode first, then a VM executes the bytecode, and it runs 5 times faster than the Java version).
In the Java version, you rely on Java's hash tables, garbage collection, etc., but in the C version you build these things yourself, from scratch, which of course is where you learn a lot, as least speaking for myself.
The author is an incredibly talented developer and writer. Much of the fun is in the little asides and drawings throughout the book. Some random tidbits I enjoyed learning about, off the top of my head:
-dynamic arrays. After doing it in C, I can see it's actually quite trivial to implement.
- modulo with a power of 2. Don't use modulo in this case. Use bitwise And with the number-1. Way faster. I already knew this but it's fun to be reminded.
- "NaN boxing" (all data types are stored as doubles, and he relies on the fact that a 64-bit pointer only uses the lower 48 bits. So have at it with the upper 16 bits. Could blow up in the future but apparently safe for now).
- a nice refresher on hash tables
- byte addressing, padding / word alignment.
- garbage collection. You build this yourself in C.
- keep data near each other. Heap allocations all over the heap might mean more cache misses. Keeping your data smaller and together means the cache works better. There are some design choices he makes in the book to reduce cache misses.
Highly recommended!
|