

-
The license is here:
https://github.com/munificent/craftinginterpreters/blob/mast...
Though now that I look at it, I apparently completely forgot to specify how the images should be licensed. Oops.
It's not a big deal and I really appreciate you reading and writing about the book, but I would prefer to not have the images reused without attribution.
-
CodeRabbit
CodeRabbit: AI Code Reviews for Developers. Revolutionize your code reviews with AI. CodeRabbit offers PR summaries, code walkthroughs, 1-click suggestions, and AST-based analysis. Boost productivity and code quality across all major languages with each PR.
-
Fun writeup. When I went through and implement the book in rust (https://github.com/jcdavis/rulox), I just used Rc and never really solved the cycle issue.
I'll +1 and say I highly recommend going through Crafting Interpreters, particularly as a way of building non-trivial programs in languages you are less familiar with - If you just follow the java/C example you are tempted to lean into copy/pasting the samples, but figuring things out in other languages is a great experience
-
Crafting Interpreters is such an amazing work.
There's at least one other Rust implementation of lox that I know of (https://github.com/tdp2110/crafting-interpreters-rs) (no unsafe)
It's always interesting to see how different people approach the problems in their own language or relative isolation. I agree with the author of the article, the real value of the original work lies in avoiding copy and paste.
-
I have run into a lot of similar problems writing a state management framework for Rust (wip at https://gitlab.com/samsartor/hornpipe) and at one point dispared that I would have to abandon Rust and make a whole new reactive language. But the last couple years I've got it working really nicely with weak references and software transactional memory. Every reference is `Copy + Send + Sync + 'static`. And you can mutate objects by having a transaction make a local bitwise copy, which will get atomically merged and swapped on commit. The old copy gets kept around for undo/redo purposes. I've still got a boatload of algorithmic puzzles to solve to provide all the MVP features, which will take a while because it isn't my full-time job. But the details seem technically sound.
I did write a blog post about some of my design thoughts, although it doesn't dig into the technical guts: https://samsartor.com/guis-3/
-
Nice article. A couple of years ago I also implemented Lox in Rust. And I faced the exact same issues that the author describes here, and I also ended up with a very similar implementation.
I also wrote a post about it: https://ceronman.com/2021/07/22/my-experience-crafting-an-in...
I ended up having two implementations: One in purely safe Rust and another one with unsafe.
Note that if you're interesting in the "object manager" approach mentioned, I did that in my safe implementation, you can take a look at https://github.com/ceronman/loxido
-
I implemented exactly what you were saying here (https://github.com/ltungv/rox/commit/6a611e7acb3b36d0a3a4376...). But where's the fun in that?
-
This is really well-written!
Shameless plug: you may want to check out https://github.com/ajeetdsouza/loxcraft. I too followed the path of "ignore safe Rust for maximum performance". It got pretty close to the C version, even beating it on some benchmarks.
-
Nutrient
Nutrient - The #1 PDF SDK Library. Bad PDFs = bad UX. Slow load times, broken annotations, clunky UX frustrates users. Nutrient’s PDF SDKs gives seamless document experiences, fast rendering, annotations, real-time collaboration, 100+ features. Used by 10K+ devs, serving ~half a billion users worldwide. Explore the SDK for free.
-
Just for reference, the gc-arena crate (https://github.com/kyren/gc-arena) we use in Ruffle's Actionscript 1/2/3 interpreters and across the entire engine, does this. As far as we know, it's safe and sound, at the cost of some limitations, mainly: to compile-time prevent sweeping while holding onto Gc references, every struct and function touching Gc objects passes an extra 'gc lifetime. And not being able to run the GC at arbitrary time can be major issue depending on what you're doing; in Ruffle we incrementally collect between frames and pray that no single frame will ever allocate enough to OOM in the middle of it :)
And yeah, RefCells everywhere.
-
I did something very similar to this myself. My GC implementation was pretty heavily inspired by manishearth's Rust GC.
My swing at the Crafting Intepreters in Rust can be found here: https://github.com/mwerezak/sphinx-lang
Although, at the time I was really interested in Lua's syntax so for extra credit I designed a completely different syntax for Lox.
I'd love to revisit this project sometime and implement a register-based VM similar to Lua's.
-
There's also more recent implementations such as https://github.com/chc4/samsara (quite similar to https://github.com/pebal/sgcl , which is for C++. Both implement a concurrent tracing algorithm whoch allows for reduced latency compared to simple mark+sweep).
-
There's also more recent implementations such as https://github.com/chc4/samsara (quite similar to https://github.com/pebal/sgcl , which is for C++. Both implement a concurrent tracing algorithm whoch allows for reduced latency compared to simple mark+sweep).
Related posts
-
Markdown's Big Brother: Say Hello to AsciiDoc
-
QBE – Compiler Back End
-
Implementing Crafting-Interpreters in Rust - Chapter 18 - Strings
-
Loxcraft: A compiler, language server, and online playground for the Lox progra
-
loxcraft: a compiler, language server, and online playground for the Lox programming language