I previously mentioned that I’m porting Raven from Julia to TypeScript. That work is ever so close to done – 7,374 lines of Julia source have become 7,145 of TypeScript, and it’s really just finishing touches (though of course the final line count won’t be identical). Once the basic translation is finished, I can look forward to debugging several thousand lines of essentially untested code – we’ll see how that goes.
I can say with some conviction that TypeScript itself is not the main benefit of moving. If it were practical to run Julia in the browser I’d take that in a heartbeat. Given the browser constraint, TS is the most practical option, but the warts are big and leaky (as I’ve written about). I find it far less pleasing to read code in particular – an important part of my job now that LLMs are doing much of the writing! There’s just so much line noise. Something as basic as indexing like xs[i] becomes some(xs.get(i)) (the some being to turn null pointers into run-time errors). In Julia I can compose elegant, clear one-liners out of universal set operations; in TS that becomes a nested for loop with messy explicit indexing (or otherwise a bunch of one-off set utilities that only apply to specific data structures).
It helps that OpenAI’s Codex (my new favourite assistant, which I’ve rarely hit limits on despite using the cheapest plan) knows TS well and can easily pump out code, guided by the type checker. But the bottleneck quickly becomes what the models aren’t doing – reviewing and correcting their own output, obviously, but also addressing bigger-picture questions. Codex’s willingness to do something, anything, to fulfil the brief can quickly become a downside; it is at its most deranged when the task I’ve set isn’t quite practical, but rather than identifying the blocker it ploughs ahead incoherently. And it certainly won’t consider the long-term consequences of its choices – what matters is passing the type check right now.