Today I LearnedRSS

December 2025

2025-12-16
We Dance To All The Wrong Songs

Both of the installations mentioned are actually pretty cool.

Still not a fan of how high-end physical art is basically valuable in so far as it facilitates tax evasion and money laundering. Still upset at all the assholes who used and continue to use the technology to destroy the lives of working class people. Still think fanatic techbros are something we as a society really need to address at some point. Still think buying a receipt for a link to a JPEG is absurd. Though I guess "certificates of authenticity" and the similar "deeds to real estate on the moon" have been with us for a while.

On the other hand, an extremely convoluted way to reopen those financial loopholes (as it would have to be) has provided a genuine window for high-end physical artists to make a lot of expensive art installations feasible for a little while without as many middlemen taking a cut. That's pretty cool. All the also-rans with ugly random character generators finally went home and now there's some space to appreciate the real work that's been going on.

2025-12-12
Lecture Friday: Stop Writing Dead Programs

So much here is spot on.

I enjoy Python and JavaScript exactly because their most popular runtimes include a REPL and by extension, builtin debugger. That alone provides many of the live coding features he's talking about. They're not perfect, and TypeScript's running the other direction in the name of boxing people into VSCode, but those examples can help if you're unfamiliar with languages and runtimes from Clojure, Erlang, and Smalltalk.

But it's slow... The refrain I can hear many people saying is, but these languages are slow. No, the language is an abstract concept. You're confusing the runtime or build artifacts of a given compiler with the languages. To be fair, the talk also blurs the two for shorthand. Cpython is currently really slow. No debate from me there. PyPy is much faster. Nuitka is faster still. And Numba is likely faster than what you'd program in Rust or C++ and takes a fraction of the time to code. Idiomatic language use can also lead to slow code, but that's a skill issue.

No, the language runtime being slow isn't generally an issue. There are billion dollar companies running Python at scale in production. It just drives up the hardware costs and limits what you can do on a single machine for a reasonable price in a reasonable amount of time. A reasonably priced computer can still do an insane amount of compute though. Erlang programs run a large share of all the computers in the global telephone network. Many games grossing a million dollars or more have been built in Python, Lua, and GML. That said, why waste the compute unnecessarily? I'm constantly drawn to Jai, Zig, and Odin entirely because you shouldn't need a runtime penalty in a production environment.

What I'd really like is the ability to split production from development further when it comes to runtime. Build systems often already have debug and release builds. Zig even has the concepts of ReleaseSafe and ReleaseFast. If you then think about a concept like attaching to a running production system with your runtime, or the ability to both interpret and compile your language as truly first class primitives. Really design the language around iterative highly introspective systems with injectable runtime binding.

An ideal would be a zero cost development runtime. That is, you only pay the runtime cost when you attach to the program. You might object that production builds do a bunch of optimizations. Sure, but what's to say you can't hijack the control flow and feed it to an interpreter? Then you can run the source code that went into those optimized routines in a manner that provides full reflection, introspection, and manipulation. Even if a dozen functions have been inlined and fused, you could run an interpreted version of those by patching the landing sites. The environment would look exactly like you'd dropped a import pdb;pdb.set_trace() but it would be dynamically patching the optimized code paths to the interpreter. I'm sure it's way more complicated to get the optimization scoping right, but there's likely a reasonable tradeoff to scoping since optimizations usually need to bound their search space anyway to prevent combinatorial explosions.

Now we go a step further. You can iteratively program some of that code. Like incremental builds but without having to restart the process. Bring in some of that Bret Victor, hot dispatch looping. Add some of those automatic data structure visualizations by having more standard library data types with first class debugging visualizations. That's kind of what Python's __repr__() class methods were all about, but I've more often seen them abused in ways that make debugging harder by messing about hiding things for aesthetics sake instead of easier by gathering and presenting the rich inner workings of a given data structure.

The ability to essentially connect to your application like you're SSHing into it. Able to run individual functions through the live interpreter, to build them up in a editor and debug them live. The ability to address what Erlang would term processes, but which could be called threads, coroutines, or workers. Monitor their call graph, interrupt them with breakpoints, kill them, spawn new ones, or blue-green upgrade them in-place, all using the attached runtime harness. Almost like independent processes but with robust IPC.

Zig, Jai, and Go took a small step forward with their build system being able to quickly compile and run the program, but yeah, still not great at scale. Builds in very large projects can still take a while, especially as the number of generics expand. In these languages I haven't yet experienced full Rust or C++ level hour long build cycles, but they're still not instant. Not being able to attach to the compiled program, introspect and modify it is really limiting. I shouldn't be tempted to add print statements and restart the program. I should be able to start the program once when I sit down to work and then edit, debug, and evolve it while it's running. Not hot reloading, but proper multiprocess software development. That probably also means state snapshots and time travel debugging. I'm only usually working on a handful of codepaths at a time. The rest of the program should be running as a fully optimized build with only sections in this interpreted slow path.

If any of this sounds cool, check the talk. It's not a talk about what languages you should be using, it's a talk for language developers to really consider looking back at what cool things already exist. Making the case that if your language doesn't have these sorts of features, you're spending a lot of extra unnecessary time fiddling with all the work you have to do around the actual work.

2025-12-05
Lecture Friday: Just Draw!

This is exactly what I've been talking about when I say you need to practice more. This! This isn't just about drawing. It's about practicing your craft. Its about how you become great at anything. Programming, music, art, speaking Spanish, playing basketball, whatever. You just need to do it. The more you practice, the better you'll become.

The interenet has made measuring yourself, of getting bogged down in the meta, and endlessly distracting yourself with theories and critique, far too easy and fun. Stop sharpening your axe and just start cutting shit. Sure it'll be rough and ugly. That's how you get better. You cannot just think yourself better. You have to practice.

He's right on the money complaining that technology has held many people back. Too many people who decide they really want to learn a skill get distracted until they give up because the internet talks about all the technology they supposedly need. It creates this artificial impediment to actually doing the thing. They need a stylus hooked up to Photoshop with the right set of brushes, or need a MIDI keyboard hooked up to a DAW with the right set of VSTs, instead of things as cheap and easily obtainable as a pencil and some paper or a used guitar or keyboard. Heck a stick and some mud or a drum-able surface is all you need.

For programmers it's getting all wrapped up trying to download and use VSCode or trying to install Linux or whatever instead of opening a simple text editor and just hacking out a script to automate something or make a little webpage or game.

The best part about a pencil or an instrument is that the moment you start interacting with it, you start to create something. Something ugly and raw, your first time doing anything is going to be awful, but you quickly see the possibilities. It's real. You aren't faffing, you're failing, and failing is the first step to improving.

Sure, after you're practicing all the time, you can start to improve on the process. Use resources to learn new things to try. But I often tell people considering a gym membership to start by going for a walk every day. If you can't commit to a walk, be honest, you're not really going to commit to the gym. Same goes for practice. If you just start by watching lots of videos or buying some fancy gear or whatever, you're not likely to stick with it. You spent a bunch of time and money but you're still right where you started. You'll know how to talk the talk, even look the part, but you still can't walk. You won't be able to create anything of your own worth celebrating until you're regularly practicing.

So please, just start practicing. It's a much better use of your limited time on earth compared to spending it consuming things other people make. The things you've made will outlive you. The things you've consumed or only thought about die with you. Change only happens when we physically do things, create and build things. Not for others, but ourselves. Create things you enjoy. Share them if you like. But do it first and foremost for yourself because making things makes us happy.

I'm some goober typing words in a text editor and you're now reading them. That's the power of creation. And very rarely, someone like you might really enjoy that but we can't enjoy anything if you don't create something. Draw the pictures you want to see. Play the notes you want to hear. Make the videos you want to watch. Build the furniture you want to use. Write the works you want to read. Fabricate the cloths and accessories you want to wear. But start small, make it a habit, and create things because nobody can stop you.

2025-12-02
Windows Drive Letters Are Not Limited To A-Z

I have no practical application for this knowledge, but it's one of those really cool obscure bits of Windows internals. Like knowing about alternative data streams in NTFS, or how you can't normally name files things like con, aux, or prn, because path resolution has devices like these globally available. Why? Because Windows has its roots in CP/M and takes backwards compatibility very seriously.