I'm coming up on a chunk of vacation, and I'd like to work on a technical project during that time. I have a couple of plates already spinning; Boltzmann documentation, for example. The itch(es) I'd like to scratch are:
- Parsing in Rust, possibly using
- Learning more about WASM and WASI, possibly using them as a language compile target.
- Revisiting control flow graph generation of JS in Rust, using ratel, RESSA, or esprit.
- Doing something graphical: some sort of map generation would be neat.
There's quite a learning curve for me here; I'd probably be picking up
Amethyst, Rendy, or
Each of these has a research component: what is the state of these ecosystems? How do the various pieces fit together? What does it look like to work with these in a borrow-checked language like Rust?
So, breaking down the projects a bit:
Write a tiny language
Admittedly, there's not a huge technical need for the sort of langauge I'd write, nor or any sort of gap in existing tooling I'm attempting to address! I'm interested in "walking the path": what does it look like to write a language today? What role might WASM play in early prototyping? What gaps exist?
And indeed, writing a scripting language is on my personal programming bucket list. I've written tons of parsers in my day (and a single control-flow-graph generator leveraging partial evaluation), but I haven't had the chance yet to write an executable language.
I plan to start small: iterate on a LISP-like language at first. Targeting
WAT ("Web Assembly Text format") and emitting WASM may be a good start. That
would let me target Node's WASI API ("Web Assembly System Interface") to
get started, or perhaps wasmtime. Eventually this could lead to writing a
self-hosted runtime using
uvwasi. (That would be a fun
learning experience, since it'd take me through using
Control flow graph generation
- Visualize code diffs from a novel angle: instead of looking at the textual change, two graphs would be compared and the differences would be displayed visually. (It would be easy to catch that new code introduces an exception edge when looking at two directed graphs, less so in textual form.)
I cut that Gordian knot by backing into partial evaluation: as I walked the
graph I would keep a stack state machine that would allow me to make assertions
about certain exception edges as they appeared: as an example, if I had drawn
an exception edge for
x is undefined earlier in the graph, I could omit the
edge on the next (straightline) lookup of
'use strict' x += 1 // draw an exception edge: what if "x" is undefined? x += 2 // if we reached this point we definitely know that "x" is defined!
Approaching the problem this was expedient, but tipped the scale on other load-bearing decisions: because it had the stack machine information available to it, ESControl aggressively inlined functions. Eventually it reached a point that for some small programs, I could generate ESControl IR and run the program step-by-step with the same output.
I'm interested in revisiting this in Rust for a couple of reasons:
- I never got to the point of visualizing code diffs as control flow graph changes, and I'm still intrigued by that
- I'm interesting in taking door number two, so to speak: separating the control flow graph generation from a simplification step that would run the partial evaluation necessary to erase edges from the graph.
This would require familiarizing myself with the state of JS parsing in Rust. I would not be mad about that.
This one is a bit out there. At my $dayjob we've been tasked with rethinking how delivery fulfillment works; I've become enthusiastic about the idea of modeling this as actor-owned task queues. Put another way, the data the system operates on would work much like how real time strategy games model commands issued to units. From there we'd layer on systems responsible for generating and assigning efficient task queues. (This might not seem like much of a brain-wave, but to be honest the way the system works right now was clouding my framing of the problem.)
Of course, thinking about real-time strategy games got me thinking about game programming again; at the same time, I've been missing some of my more visual experiments. It'd be fun to build a terrain or city generator, then model unit task queues on top of that! Kat's recent work in this space is inspiring, also. (The presentation Kat linked to earwormed me.)
Currently reading / open in tabs:
Yoshua Wuyts' writeup on compilers: Yosh is super thoughtful and thorough; I'm excited to read more of his writing. (Compliments aside, you can imagine how a writeup on compilers might dovetail with my current interests!)
"Why we love Rust": a nice grab-bag of tips & tricks learned while delivering
an impressive low-latency video & audio streaming solution. I'm going to try integrating
some of the tools they suggest, like
Essentials of Metaheuristics: linked by a co-worker, Eli. As you can imagine, optimizing delivery involves a lot of (NP-hard) problems, for which heuristic approaches are a good fit. My experience with this is a bit distant, so I am refreshing my memory by re-reading the simulated annealing article on wikipedia. (This also dovetails with my desire to build a CFG diffing tool, which abuts the NP-hard-in-the-general-case longest common subsequence problem, for which a dynamic programming approach can solve specific cases in polynomial time. This is all to say: it's up my alley, and look, there's a Rust library for it!) I'm also taking a peek at Optaplanner on his recommendation.
Grain Language: a new language! Linked by Blaine. I like Blaine's taste; if he's enthusiastic about a language it's probably worth checking out.
StaffEng.com: A great overview of what work in a staff engineering position looks like. I feel some relief at the seeing the enumeration of the types of roles staff engineers play at companies: I am somewhat allergic to working at large companies with lots of process, so I'm not a great fit for teams that use staff engineers to enforce process: whether that's serving as architecture review boards or tech leads responsible for assigning work. However, I have it on other folks' authority that I'm a good teacher, and I know how to tactically deploy my technical skill in service of my larger strategies. I'm in my feelings about this one still -- that last year at NPM really did a number on me, not least of all because the goalposts of what staff engineering meant changed all at once. It's probably worth a more complete blog post in the future.
Other thoughts which may yet become blog posts:
I've been ruminating a bit on my career progression lately. One of the aspects of staff engineering I'm interested in is how we process negativity, or grumpiness. It seems to me that as a profession we tend to reward negativity, so I (& others) displayed more of it when mid-career. I've walked a lot of that back over the last four years, but false positivity isn't tenable in the long run, either. I've been stewing on Steve Klabnik's keen observation:
As a programmer, I think it behooves us to think about not just the values that we hold, but the values of the people that use our software hold and, as a programmer, you should use tools that align with your values. I really like programming languages and learning new ones, but there are some that I have seen where I'm like, "You know what? This language is not for me, so I'm just not going to use it." I'm not going to denigrate any languages by naming them, but it's true that I would be unhappy if I had to program in some languages and that's because they value different things than I value and that's totally chill.
Ceej relayed the following from her husband, David:
Anger is a useful signal: it means your values are being violated in some way!
Speaking of grumpiness because of violated values, I'd like to see a positive workflow for ES Modules framed, if possible. Right now the story is all veggies and no dessert.
Finally on this note: I've been thinking about React SSR quite a bit lately. The thought bouncing around in my head is: React's origin as a tool for managing a live DOM makes it ill-suited for use as a server-side template language, which is how most React SSR solutions position it. It's another thing I find myself grumping about, and it might be worth digging into in the future.