Last weekend I watched this video of Andreas Kling prototyping a JIT compiler for his Ladybird browser:
It’s a very interesting video, for two reasons.
One: if you’re interested in how bytecode VMs and JIT compilers work, it’s all in there, explained step by step. A goldmine, really. If I had had a video like that 6-7 years ago I might not have written my books.
Two: how Andreas builds this JIT compiler is endlessly fascinating. It’s clearly visible that he’s spent thousands and thousands of hours of his life programming. It shows up in the large (hey, he knocks out a JIT compiler in 1.5hrs) and in the small – little tricks and moves and shortcuts. The latter is what’s so fascinating, because usually you don’t catch these small things on video, forget that you did them or don’t think they’re even worth mentioning.
Here we do have them on video and when bundled up like this you see that the small things add up to a lot.
I had to smile right at the start when Andreas starts with a single file, only adds the necessary boilerplate to exit with code 0, adds it to the build system, compiles and runs – just to make sure it’s all wired up correctly and he’s ready to go. I’ve seen engineers run straight into multiple-modules land and write a bunch of code only to then realise that it doesn’t build and they will have to rewire the whole thing to make it work. Good move from Andreas right there.
Then there are these short moments throughout in which he very quickly reorganizes the windows of his IDE and terminals. He’s very fast. I had to pause to figure out what’s going on and how to replicate it in GNOME.
He’s fast in general: he types really fast, he changes windows quickly, he writes little JavaScript files with cat
and Vim in a few seconds, he says “let me just dump this bytecode so we can confirm” and proceeds to write 50, 60, 70 lines of code – I’ve seen programmers simply not do a debugging step for days because it would take 50 lines of code to write instead of 2 print statements.
He also navigates through his files by searching, something which I also do and got from Bram Moolenaar’s Seven Habits of Effective Text Editing. That made me smile again.
Then there’s Copilot. It’s all over the video. I haven’t counted the “Thank you, Copilot”s, but there’s quite a few. Copilot fills out the bytecode interpreter, Copilot writes assembly, Copilot writes methods for the JIT compiler. Andreas uses Copilot consciously, which, if you haven’t seen it, might sound odd – it’s auto-complete after all. But take a look at how he pauses here and waits for Copilot to fill out the main switch
statement of the JIT compiler, or how he watches carefully and hits the tab key occasionally to guide Copilot along, having it write machine code. Very interesting to watch, especially since people claim that “these tools” only make you faster when you work on boring or boilerplate code. I’m not sure whether there’s a 10x speedup, but I’d say there is one. I’ll be using some of Andreas’ tricks with Cody in Neovim.
My favorite moment in the video is when Andreas fact-checks what Copilot generated. He doesn’t just fact-check by looking at the code and thinking “huh is this correct?” No. What he does: he uses cat
to write the raw machine code bytes that Copilot generated directly to a test.asm
file, then assembles it with nasm
, then uses ndisasm
to disassemble it again and ends up looking at the assembly instructions that map to the raw bytes. Now that’s how you should own and use your tools.
The overall impression I get from the video is: programming for Andreas is effortless. Sure, he knows the domain and probably prepared for this video and wrote the JIT compiler once before, but still: he’s fast, he writes a lot of code, he debugs without problems, he has mastered his tools and uses them as tools, not as something to wrestle with.
I’ve paired with and interviewed a lot of programmers and this effortlessness is not universal. For some programmers, writing code does require real effort and they do it only if they must. They wouldn’t write a throw away program, because why throw away something into which you put so much effort?
Compare that to Andreas in this video. His goal is to write a JIT compiler, but he starts by writing a bytecode interpreter. Technically he doesn’t have to, but he does it so he can verify that his JIT compiler and his VM are working. Writing code is not an obstacle. It’s just something he does.
He’s at ease, he’s playing, he’s having fun. There might be some effort involved, but there’s certainly no strain.
It’s a very inspiring video and the thought it left me with is this: between all of the usual advice on Becoming A Senior Engineer — the (valid!) thoughts around communication, architecture, tradeoffs, and so on — it’s very easy to lose track of one thing. Getting faster and better at programming, trying to produce more with higher quality, should probably still be the #1 goal and when you’ve reached it, it looks very impressive.
Love this.
The way u described it, awesome, u were deep, u have payed alot of attention to the details