RC Week 3 — Realignment
15 min read July 21, 2024 updated: July 22, 2024 #rc #programmingSummary: I am building a Web Browser, learning Zig, doing a lot of pair programming, and trying to pace myself so that I don't wear myself out and crash. What follows is a semi-cohesive summary of my experience thus far, mostly for purposes of keeping myself accountable, and having a record of what I have been trying to do. It is less polished than my regular writing because I just wanted to get it out.
anna nope: Whoa, this looks long.
Yeah.
It has been both entirely predictable and somehow still hard to accept that time goes very fast, and I am already ¼ way done with my batch at the Recurse Center.
It has also been both entirely predictable and somehow still hard to accept how much I've already had to adjust my expectations and plans from what they were when I started.
At the beginning of my batch, I worried whether I'd be able to find the kind of project that would have me work "at the edge of my abilities" but also bring me joy, and not have me end up feeling stuck or spread too thin. What should have been predictable, and yet somehow was not something I had considered, was that those projects, at least right now, turned out to be something that wasn't on my radar when I started my batch at all.
§Plans vs. reality
Looking back at the project ideas I listed in my first post, there was obviously too much. Formal methods, and reading papers about databases, and building a database, and learning Zig, and graphics programming, and operating systems, and more. Many of those would realistically require me to dedicate multiple weeks to them individually in order to gain any depth, and I have 12 weeks total.1
On top of that, I took the advice someone gave at the start of my batch, and spent most of my first week attending every call that sounded remotely interesting. I appreciate that advice, because it made me explore things I would have otherwise not tried, and meet people I might not have met — especially being remote — but it also made me accumulate even more things I wanted to pursue, and which I could not hope to fit in the time I have.
So, encouraged by workshops and advice from RC faculty, I had to put many things aside, so that I could get more out of the ones I kept. And that's okay.
anna nope: Or you could try sleeping less. That's up to 7-9 more hours per day to become "a dramatically better programmer."
Uh... I don't think that's a good idea.
anna nope: Weak.
§Some of the very interesting things I wanted to do that I am probably not going to do during my batch
In no particular order:
-
ARENA. I learned about this course during my first week. While some of the earlier parts, like implementing various neural network architectures, backpropagation, and gradient descent from scratch are things I've done before, the course ultimately focuses on learning to interpret and explain more complex models that are conceptually similar to ones that power state of the art LLMs. This focus on safety and interpretability would have probably benefited my ML work... but it also felt too close to my ML work, and I wanted my RC batch to be about working on things I don't get to work on when I, well, work. Still, I have the course bookmarked, and hope to be able to come back to it in the future.
-
Red Book. I gathered interest, and set up the initial meeting, and started reading the papers... and realized that I wanted to spend more time building things, especially when I have a rare opportunity to do so with other people. While reading the Red Book and participating in the discussion group (that I sort of started and then dropped out of) would have also likely been a rewarding experience, I ultimately decided that this is something I can come back to after my batch ends. And I definitely want to come back to it.
anna nope: 👍
-
Graphics programming. There is currently a great group of people working on graphics-related things at RC, but I have not found adequate time to dedicate to this. Alas. I might be able to tie some graphics-related work to a small-ish game I want to attempt. We'll see.
-
OS things. I continue to lurk in the OS discussion group, and did a bit of reverse engineering of a Windows application for Impossible Day (a day when Recursers are encouraged to attempt something beyond their abilities), but I've had to shelve my plans to try building my own OS, or kernel, or whatever else, for the same reason as my plans to work on graphics. Too many interesting things that need dedicated time, and too little of that actual time.
§Some things that feel like they're slipping away which I still want to hold on to
-
Building a database. I started a CodeCrafters course to build SQLite from scratch in Zig, but got stuck early on, and left it since then. That course may be a bit too hands off for me, but someone else linked to a tutorial for building a SQLite clone in C, which might be more my speed, and reimplementing it in Zig would help me both reacquaint myself with C, and understand it more deeply because I always have to think harder about code when I am translating it to another language. So I still hope to do this.
-
Formal methods (TLA+). Unfortunately, there aren't any Recursers in my current batch who also want to learn formal methods, and I've found it challenging to motivate myself to continue. I did get to experience how frustrating the TLA+ Toolbox is, which I hear is a decent way to start. There are also some Recursers from past batches who have shared their experience with formal methods and adjacent topics, like Software Foundations. That has given me even more things to explore! I also watched cceckman wrangle with Coq and ultimately succeed in making it prove a theorem, live, which was — genuinely — as thrilling as watching someone score a tricky goal in soccer, and was probably my highlight of that day.
§What I've actually ended up spending most of my time on
§Web Browser
At some point, someone mentioned Web Browser Engineering, and I ended up getting completely pulled into that. Because I am doing it in Rust and not Python, like the book recommends, I have to keep going off the beaten path. This has been good and bad. Doing it in Rust has forced me to understand more about things like low-level networking and the mechanics of a memory-safe caching system, which I appreciate, even if those are not the point of the book itself. But it has also caused me to sidetrack myself by spending way too much time figuring out those low-level things or just plain yak shaving.2 Still, I now have a janky, text-only, CLI browser that I think does HTTP 1.1 kind of right, or at least not completely wrong.
My current challenge is building a GUI for it. Rust has 11+ GUI libraries, none of which is the obvious choice. I am currently going with Rust bindings for GTK 4, because it seemed like the most mature, but it's also, by the nature of being GTK, not very conducive to writing idiomatic Rust.3 Still, I hope to get it working.
anna nope: How's that going?
Uh.4
§Cryptography
This was also not something on my mind when I started the batch, but something I realized I am very interested in. I haven't done much other than pair on some basic cryptography-related projects and look over the cryptopals challenges, but I want to dive into it more.
§Zig
I have spent some of my time so far writing Zig, and want to write more. I've enjoyed Zig so far, despite it having less polished tooling and a lot less documentation than Rust.5 I love that it's explicitly not safe, and explicitly makes you think about sound memory management — it's a refreshing paradigm shift for me. And in some ways I feel that Zig goes even further than Rust to make sure the programmer handles potential errors, while requiring less boilerplate to do so (with the caveat that I am very new to Zig and may be unaware of a lot of the internals there).
There are some design quirks I am wary of, like the compiler magically deciding whether to pass something by reference or by value, which feels odd for a systems language.6 Still, I feel like Zig is the closest language I've ever experienced to a "better C", while acknowledging that C itself is not going anywhere for a very long time. I want Zig to succeed, and be there for it.
I am also tremendously grateful for the Zig enthusiasts at RC who have helped me with learning it.
§Pairing
RC emphasises pair programming, and I've tried to take advantage of that as much as I could by pairing almost every day, sometimes multiple times a day. Not all of my pair programming experiences have been equally productive, but all of them taught me something, and some tremendously helped me get unblocked and get things working, or dive into things I wouldn't have spent much time on by myself, so the highs have been very high, and very worth continuing the effort. Pairing with other Recursers has also exposed me to different ways of thinking and solving problems, and has allowed me to dive into domains I otherwise probably wouldn't work on.
As Nicole said in one of her own RC reports, if you're not careful, pair programming can turn into a performance, both if you're the driver or the navigator. As the navigator, I initially found it challenging to balance telling the driver what to do versus guiding them to a solution versus realizing that their solution might be just as valid as mine, all while feeling like I have to have a solution if they're feeling stuck. As the driver, I have sometimes found it challenging to get out of tunnel vision when I have a particular approach in mind, and take in an alternative option the navigator is suggesting, and also to be able to come up with a great solution on the spot.
I believe I have been getting better at both, and just having another person to talk to while working on something — regardless of whether I'm driving or navigating — can be very helpful.
And I think every pairing session has helped me improve my communication overall.
§Miscellaneous
§Highlights
- A casual Zulip conversation about learning Rust inspired me to write a short blog post that turned into a kind of long blog post about type casting in Rust. This was the first time I ever published a technical post, and the feedback I've gotten on it has been very encouraging! I hadn't experienced that kind of joy from sharing my writing with others in a long time. But writing and revising it was also more work than I had anticipated, which is something I have to acknowledge and budget for in the future.
anna nope: 🍪
- Implementing HTTP 1.1 mostly from scratch for my browser. Parts of it were very frustrating (partially because of Rust) and did not bring joy in that moment, but when I got it working and saw my tests passing, I experienced the exact kind of programming high that I was after when I applied to RC. And it being Rust made it so that once I got it working, I could refactor the code into a better structure without worrying I quietly broke something that I might've missed in a unit test.
anna nope: Did you mention you wrote it in Rust? I think you should mention you wrote it in Rust.
§Challenges
In retrospect, I pushed myself too hard trying to explore everything I could and going to all the events I could manage to during the first week, and was both physically and mentally exhausted by the end of it. I've had to pace myself since then — not always successfully. The main lesson so far is that there are always more things I want to do than I can do, and that I won't get any joy or benefit at all if I continue agonizing over all the things I can't do, or wear myself out trying to do something when I'm past my energy limit.
I want my RC experience to be about recharging and rediscovering joy in building things, so I have to remind myself that it's okay to take a break when I need to.
anna nope: That's cool. Definitely take a break. You deserve it.
That's... actually kind of you.
anna nope: Yeah. By the way, have you been following updates from other people in your batch who are doing way more things that are way more interesting? You should think more about that. You know, just while you take your breaks or whatever.
Oh.
anna nope: Or all the time, even. Just don't stop thinking about that.
Thanks, I probably won't.
§Looking forward
I want to actually post an update every week, so I hope the next one will:
- Arrive next weekend
- Not be this long
anna nope: Yeah, because, like, no one has the time for this. Especially not you.
Thanks for the help.
§Footnotes
I am even more glad that I am able to do RC for 12 weeks, because otherwise right now I'd be at the halfway mark, and I feel like I've barely gotten into it.
Where the Zen of Python
says "There should be one-- and preferably only one --obvious way to do it" (even if that's often not the reality
in real-world Python), my personal "Anti-Zen of Rust" has been that "There is almost always a better way to do it."
When I work in Rust, there are more opportunities for my brain to worry about optimizing performance or
whether I'm implementing lower-level abstractions in an idiomatic way. Rust also often deliberately provides
multiple ways to do the same thing, and the "best" depends on your ultimate goals. At least
there's clippy to
help guide those choices.
But still, I often have to stop myself from going too deep into the rabbit hole of
This code could be more Rusty!
A big part of that is that my Rust projects are primarily passion-driven, whereas Python is almost
always something someone pays me to write, so my priorities and constraints are different.
This is not at all a knock on gtk-rs. Its authors have done an amazing job to make building GTK applications in Rust as painless as possible. But still, Rust not supporting inheritance, and having strict memory safety requirements is very different from the programming model that is natural for GTK. In practice, this means that you have to use a lot of macros, and do things like list every class in the parent hierarchy of a custom widget, or rely on runtime reference counting to manage memory while remembering to avoid reference cycles. My first reaction when seeing all of that was yikes.
I almost immediately managed to get a segfault (my first ever in Rust!) by failing to follow the documentation. That was also kind of a yikes, and ended up sidetracking my browser GUI pairing session for hours while my pairing partner and I tried to minimally reproduce the segfault and find its root cause.
If you've found Rust compiler errors cryptic, try messing up string formatting in Zig. The compiler won't even tell you where in your code the error comes from! And the standard library docs currently often give you little more than a function signature, which can be hard for a "learn by example" person like me.
Multiple people have suggested that this behavior may change in a future release, which feels like a potentially very fun breaking change.