← Back to Kevin's homepagePublished: 2021 March 7
I’ve spent the last year building keyboards, which has included writing firmware for a variety custom circuit boards.
I initially wrote this firmware in Rust, but despite years of experience with that language I still struggled quite a bit.
I eventually got my keyboards working, but it took an embarrassingly long time and wasn’t fun.
After repeated suggestions from my much more Rust-and-computing-experienced friend Jamie Brandon, I rewrote the firmware in Zig, which turned out swimmingly.
I found this quite surprising, given that I’d never seen Zig before and it’s a pre-1.0 language written by a fellow PDX hipster with basically just a single page of documentation.
The experience went so well, in fact, that I now feel just as likely to turn to Zig (a language I’ve used for a dozen hours) as to Rust (which I’ve used for at least a thousand hours).
This, of course, reflects as much about me and my interests as it does about either of these languages.
So I’ll have to explain what I want from a systems programming language in the first place.
Also, to explain why I struggled with Rust I’ll have to show a lot of complex code that I’m obviously unhappy about.
My intent here is not to gripe about Rust, but to establish my (lack of) credibility: It’s so you can judge for yourself whether I’m using Rust’s features in a reasonable way or if I’ve totally lost the plot.
Finally, while it risks falling into the dreadfully boring “language X is better than Y” blog trope, I feel that it’d be more helpful to some readers if I explicitly compare Rust and Zig, rather than write a wholly positive “Zig’s great!” article.
(After all, I’d steadily ignored six months of Jamie gushing about Zig because, “that’s great buddy, but I already know Rust and I just want to get my keyboard done, okay?”)
What I want from a systems language
I was educated as a physicist and learned programming so I could make data visualizations.
My first languages were PostScript and Ruby (dynamic, interpreted languages) and I later moved to JavaScript so I could draw on the web.
That led me to Clojure (using ClojureScript to draw on the web), where I’ve spent much of my career.
In 2017 I decided to learn a systems language.
Partly this was intellectual curiosity — I wanted to become more familiar with concepts like the stack, heap, pointers, and static types which had remained mucky to me as a web developer.
But mostly it was because I wanted the capabilities that systems languages promised:
To write code that was fast; that could take advantage of how computers actually worked and run as fast as the hardware allowed.
To write applications that could run in minimal environments like microcontrollers or web assembly where it just isn’t feasible (in time or space) to carry along a garbage collector, language runtime, etc.
My interest was not (and still isn’t) in operating systems, programming language design, or safety (with respect to memory, formal verfiability, modeling as types, etc.).
I just wanted to blink the litle squares on the screen on and off very quickly.
Bas
(read more)