RC Week ... 7?
11 min read August 18, 2024 #rc #programming #zig #rustDear blog,
It has been almost a month since my previous update. How did that happen?
§Time goes by at a (mostly) constant rate,1 but my energy levels fluctuate wildly
Unfortunately, even though I enjoy sharing my writing with others, writing also takes a lot of energy. It is too easy for me to skip blogging when my energy levels are already low (for reasons I explain further down). I usually write on the weekends, but after spending so much energy during the week, I needed my weekends to provide me a break (and taking breaks without feeling guilty has always been hard for me, as it has for others).
§Building a simple web browser GUI really took it out of me
As I mentioned in my last post, I am following the Web Browser Engineering book, but in Rust instead of Python. I also mentioned that my challenge at the time of writing that post was choosing a Rust GUI framework among the many unstable, or semi-experimental, or kind of unergonomic options on offer. And finding one that worked exactly the way I wanted so that I could follow the book's approach, if not exactly, then at least in spirit.
The Browser Engineering book has you build a GUI in a very manual, no-frills way. Instead of using a GUI framework's high-level abstractions like widgets, it has you draw text to the screen 'directly,' meaning you manually figure out where the text should go on the screen given the size of the text and size of the window, then put your text at that exact place.
The book uses Tk, likely because Python has Tk bindings in its standard library. Some cool people have published crates with Tk bindings for Rust, but one crate might not work on macOS (which is my primary OS), and another is unmaintained.
So it took me, like, 3 weeks (??!) to find a GUI framework in Rust that would let me put some goshdarn text on
the goshdarn screen at the exact goshdarn x, y
coordinate I wanted to goshdarn put it.
-
I first tried gtk4-rs because it appeared to be the most mature. Unfortunately for me, GTK was made for serious people to make serious software, and not something silly like a toy web browser. I found no good way to bypass all of GTK's many, many layers of abstraction, and was losing myself in docs for both Rust and C bindings, so that I could just figure out a way to draw text onto the screen. I was stuck in the sunk cost fallacy mode with
gtk4-rs
for nearly two weeks, trying to make it work in a way that was close to the book, before I admitted to myself (and others)2 that I was not making meaningful progress, and finally decided to abandongtk4-rs
out and start over with... -
Iced. I think Iced is a very promising framework, and I appreciate that its creator(s) are trying to build a GUI framework that tries to work with Rust's memory management model instead of around it (ahem,
gtk4-rs
), and shift as many errors to compile time instead of run time (ahem again,gtk4-rs
).3 But Iced is also very heavily in development, with potentially breaking changes on every commit, and the docs can be hard to follow (or not exist, or not match the current codebase). To be fair, the documentation itself makes all that clear upfront, so my frustrations are on me. And there were things about Iced that I found very elegant once things clicked. But, ultimately, I still couldn't figure out how to just draw text on the screen at a givenx, y
coordinate. So, once again, I forced myself to move on and start again with... -
egui. Long story short, this was the winner 🎉
- Easy to use and get started with (as promised)
- Offers widgets and other abstractions, but doesn't force you to use them
-
Has decent docs (I have to admit that after
gtk4-rs
andIced
, my bar was very low) - Lets me put some goshdarn text on the goshdarn screen at some specific goshdarn coordinates
I am still upset that this GUI journey ate up so much of my time,4 but I'm glad that I got there in the end. If not for other Recursers in the Web Browser Engineering study group, I would've probably abandoned it.
- Recurse community: win
Still, I burnt a lot of energy on this project, and several weeks of repeatedly
rebuilding the GUI from scratch in yet another framework brought me no joy
(as much as it was a learning experience — or at least I hope it was). When I finally made my text
layout logic work in egui
,
I did feel a very high high, and that somewhat made up for the hard time I had getting there.5
But it's made me think about what I really want to get out of the rest of my time at RC — especially because, continuing to surprise no one, that time has been moving very fast. I plan to continue with Web Browser Engineering, but I also want to leave time to explore other things. More joy, less frustration about implementation details.
And more opportunities for collaborating with other Recursers.
§Struggling to build a SQLite clone in Zig made me appreciate other Recursers even more
One of my goals for my batch at RC has been to learn Zig. Another was to learn how databases work from the ground up. I have been trying to make progress on both by implementing a SQLite clone in Zig.
I originally started this project by trying to follow the Codecrafters course. That turned out to be very frustrating for me (the course, at least in its Zig version, offers little guidance beyond a high-level structure), and I quickly abandoned the project and stopped attending the Build Your Own Database study group.
Then, a fellow Recurser suggested Let's Build a Simple Database in C, and I thought it would be perfect both to practice reading C, and writing Zig, and understanding how their database implementation works because I would need to translate from C to Zig instead of just retyping all the code as-is.6
However, with my brain being fully subsumed by the challenge of building a simple browser GUI in Rust, it took only a slight roadblock in my Zig implementation for me to put that project aside as well. It would have probably stayed put aside (read: abandoned), if the Recurser who has been leading the Build Your Own Database study group hadn't reached out and kindly checked in to ask if I had stopped attending because the time slot didn't work for me, or if there was another reason.
I admitted that the reason was that I felt bad about not making progress on my SQLite implementation, that I didn't like my reason, and that I wanted to rejoin the group.
Since then, I have been making slow but steady progress on this project, and have paired with that Recurser on my SQLite-in-C-in-Zig multiple times, with every one of those times helping unblock me. Even though he does not know Zig, his knowledge of C plus systems programming experience plus being ready to dig into Zig docs has helped me tremendously.
- Recurse community: win
§Aside
The whole Zig will magically decide when to pass parameters by value or by reference turned out to be a Chekhov's footgun, because I ran into the exact problem of getting a copy to an element where I thought I'd be getting a reference.
I still like Zig overall, but would 100% prefer less magic.
§Meta
§Pair programming, coffee chats, discussion groups
All of those are great, I have really enjoyed them, and have found them to be one of the most rewarding parts of RC. RC is the only place I can do those, and I want to make the most of that.
§End of previous batch, start of new one
Last week was the end of the previous batch, and many people I hope to stay friends with have Never Graduated. Meanwhile, this week a new batch started (batches are staggered), so there have been lots of new people to meet!
It's felt bittersweet.
§Plans and intentions
Things I have not done but still want to do:
- Cryptopals
- Learn TLA+
- Build a small web-based game for game jam
I want to continue posting about those in the hope that doing so will increase the odds of me getting to at least a part of them. We'll see, I guess.
§Blogging about it all
I failed in my intention to blog every week. I may have needed to step away from my computer to recover, but I still feel bad.
- Writing on schedule: not win
Of course, the more I put off writing an update, the more of a Big Thing it became in my mind. I really appreciate everyone who has told me they've read my posts and offered kind and encouraging feedback! It has helped motivate me to keep writing.
So, I do want to post these updates weekly, for real.
anna nope: Cool story, bestie.
... were you here this whole time?
§Footnotes
At least, assuming have spent the past seven weeks on Earth, as I have.
I appreciate everyone who observed me struggle with this and offered support, be it technical or moral.
Absolutely not trying to throw any shade on gtk4-rs here. I've said before that its authors have done a great
job within the constraints they've had, and have clearly tried very hard
to make using GTK4 from Rust relatively ergonomic. But GTK
targets languages that don't have a borrow checker (which Rust famously does),
and support 'traditional' OOP patterns like inheritance (which Rust famously does not). So, I think,
the Rust way of doing things will always be fundamentally at odds with the GTK way, and it feels nice
to use a framework like iced
or egui
(especially egui
) that works with Rust instead of around it.
Especially because egui
was my top choice at the very beginning, before I picked gtk4-rs
because
it was stable and mature, and then iced
because ... I don't know, I think I'd heard it was cool? And I was also
wary of egui
being immediate mode. In
retrospect, this concern was unfounded — ergonomics turned out to be way more critical — but I didn't know what I didn't
know.
In my moment of elation, I posted an internal RC check-in that included this:
This is a tremendous moment in the history of personal computing, on par with the invention of the integrated circuit, mouse-driven graphical user interfaces, and the Internet itself. This is why 2024 will be like 1984.
In general, when I follow courses, books, or other learning materials that target a specific language, I find a lot of value in writing my implementation in a different language. This does take significantly more time and mental energy, but I think the trade-off is worthwhile overall. Sometimes it makes me feel like I understand the concepts in the source language even better, because I need to figure out how they work in order to effectively reimplement them in the target language. And it engages my ADHD more than I could engage it by retyping someone else's code.