Vigil - A clean, fast build watcher for Zig (inspired by Bacon for Rust)
19 points by Chase
19 points by Chase
I have been exploring Zig and wanted a project that let me practice concepts from Data Oriented Design, TigerStyle (links in the readme for context on those) and simplified approaches to manual memory management that have intrigued me the last couple of years. I wanted something wildly different to Clojure (my beloved daily driver) and Zig has been a fantastic tool to explore these concepts. I'm a big fan of Bacon (check it out if you use Rust) and wanted to have a similar tool for my Zig projects so here we are. I like to think it's about 80% of Bacon's functionality in only about 20% of the code. It was a really cool moment when I was able to start using Vigil, itself, to help during the rest of it's development.
Ha, you scared me for a second! I totally remember that project of his (not the name though but I figured there would be collisions, I just decided not to even look though as I just like the name). Very fun.
It's also a funny coincidence that the same author of that project is also the author of Crafting Interpreters and Game Programming Patterns, which are the exact texts I plan on working through for my next Zig projects.
I noticed that you've got some comptime assertions enforcing an upper bound on the size of some structs (e.g. Line). I thought that was pretty interesting. Why have an assertion on a compile-time property like that? Just to be extra explicit about the upper bound?
I'm not sure how common it is, but we litter this all over Ghostty too (example). Sometimes it's due to the size being a critical property (e.g. ABI compatibility) but most of the time it's just to force the developer to stop and think and consider if they really wanted to change the size of something or not. I can't think of specific examples but I do recall triggering this and being happy it did.
I noticed that you've got some comptime assertions enforcing an upper bound on the size of some structs (e.g. Line). I thought that was pretty interesting. Why have an assertion on a compile-time property like that? Just to be extra explicit about the upper bound?
So while this project was building something I actually wanted it was also a learning exercise in applying TigerStyle and Data Oriented Design which I've been curious about but never really put in practice before. If you aren't familiar you can read about it here: https://github.com/tigerbeetle/tigerbeetle/blob/main/docs/TIGER_STYLE.md and watch a cool presentation about it here: https://www.youtube.com/watch?v=w3WYdYyjek4 I can also give you some DoD related material if you are curious about that too.
The gist is I wanted to keep the Line struct small for reasons highlighted in the comments (fit it in a cache line, etc.) and so it's my understanding of TigerStyle that you use comptime asserts in these kinds of situations to really enforce this design choice. So one benefit would be to prevent future bloat. Say I end up adding some fields to the struct down the line and it starts growing bigger and bigger and before I know it we miss out on all that DoD goodness. The comptime assert would scream at me loud and clear when that happens. The Line struct is right in the hot path for the program so the comptime assert is saying, "Hey we are consciously trying to be super efficient here and I'm putting you on notice that we will continue to do so in the future by catching any design violations at compile time." And it caught your attention right?! So your hunch is spot on.
Is it overkill for this particular program, probably. You might find quite a few examples of it in the code base tbh. But I just really enjoy what the TigerBeetle, Zig, and DoD folks are putting out there so wanted to try putting it in practice myself.