Evan Hahn (dot com)
https://evanhahn.com/blog/
My blog, mostly about programming.
フィード

Notes from September 2026
Evan Hahn (dot com)
If you follow my monthly roundups, (1) who are you?? please say hi (2) you’ll notice a smaller post this time. September was a busy month for me.Lots of feedback on a small postI published “Anecdotally, programmers dislike ‘reduce’”. I finally wrote up a phenomenon I’ve observed for years. It’s a short post that didn’t take long to write.I got a tremendous volume of feedback—more than anything I’ve ever written. Dozens of messages, hundreds of comments, shoutouts in popular newsletters…I’m even meeting up with old friends because of it!This industry, for better and worse, is moving away from the details. I like the details! I was heartened to see the number of people who care about the minutia of programming—enough to email some random guy on the internet.Cool links from online“What is the programmer interface for garbage collection? There isn’t one. Can’t get simpler than that.” From “Simplicity is Complicated”.Won’t attend, but the Small File Media Festival looks neat.“A lot of the t
10時間前

Anecdotally, programmers dislike "reduce"
Evan Hahn (dot com)
In short: from my experience, people like map and filter, but not reduce.I use functions like map and filter all the time. When I put that code up for review, my peers rarely complain. I get plenty of feedback about other decisions, but not about my use of map and filter.I cannot say the same for reduce. Often, when I’ve submitted a patch with reduce inside, I get a comment like, “this part is hard to read.” And I see reduce way less than map, filter, some, and so on.Anecdotally, I have come to believe that programmers don’t like reduce as much.I don’t know why, but I have a few theories:reduce is harder to read.reduce is less familiar.reduce can have worse performance compared to other options.reduce is less elegant in languages I use, like JavaScript, Python, and Swift. In my blissful stint as a Clojure developer, I did not get this feedback.I’m wrong, and I’m seeing a trend that’s not real.I usually just change reduce to something else and move on. Even though I prefer it, I don’t u
18日前

Notes from August 2026
Evan Hahn (dot com)
Since last month, I released some new stuff at work, clicked a bunch of links, and wrote a little bit.Things I did this AugustAt Ghost, we added analytics for automated email sequences. This helps publishers see how their sequences are doing. This simple feature turned out to be pretty tricky under the hood.Learned that Vim has a joke trigger called UserGettingBored.I continued to write for Zelda Dungeon, including an interview with a very cool ROM hack developer.Links I clicked“Libertarian futurists weren’t the only people proposing new rules for cyberspace; they just happened to be the people who ended up making the rules.” From “Democracy v the machine”.“If civil society is to remain free and vibrant, people must be able to organize, speak and connect without fear of being watched.”Learned that most Americans hate data centers. I learned this from a poll and podcast episode.I appreciated this overview of digital accessibility technologies. I definitely didn’t know about all of these
1ヶ月前

Vim's UserGettingBored autocmd
Evan Hahn (dot com)
In short: Vim has a joke autocmd called UserGettingBored that doesn’t do anything.Vim’s automatic commands feature, usually shortened to “autocmd”, lets you run code when various events occur. For example, you could implement an auto-save feature by binding the TextChanged event to the :w command.Vim has over 100 events, from “buffer was created” to “file was saved”. But one of them sticks out to me: UserGettingBored. Here’s the documentation:UserGettingBored: When the user presses the same key 42 times. Just kidding! :-)When I saw this, I was busy doing something else and it completely derailed me. “I must know more,” I thought.Here’s what I found:Unfortunately, it doesn’t do anything. It only exists in the documentation (and some tests). If you try to use it with somethig like autocmd UserGettingBored ..., you’ll get a “no such group or event” error.It’s present in Vim, Neovim, and Vim Classic.It was first added by Bram Moolenaar in July 2000, over a year before Vim 6.0 was released.
1ヶ月前

Notes from July 2026
Evan Hahn (dot com)
July! What a month!Things I did this JulyGave a talk, for ClimateAction.tech’s “Responsible AI Series”, “What I know about local language models”. “Responsible AI” can feel like a bit of an oxymoron at times, but I hope I shared something useful.Participated in the Zelda Dungeon Marathon. My first time playing a video game (The Legend of Zelda: Oracle of Seasons) on stream!Released a new version of Helmet, my Node security headers package. Most notably, it sped up the Content-Security-Policy code by about 7% for common cases.Promoted an underrated SQLite feature: strict tables.Wrote a data-driven piece about the upcoming Legend of Zelda: Ocarina of Time remake. Can the wisdom of 32 Zelda experts make accurate predictions about the new game? We’ll see.Finished moving most of my repositories from GitHub to Codeberg. A few stragglers—and some mirrors—remain, but they’re my bigger projects that require more coordination.Links I foundMy favorite read this month: a detailed history of Arabic
2ヶ月前

Prefer STRICT tables in SQLite
Evan Hahn (dot com)
In short: I prefer strict tables in SQLite because they avoid some datatype problems, such as putting text in number columns.SQLite has a feature that I think is underrated: strict tables. Strict tables help enforce rigid typing, preventing mistakes like putting text into integer columns. I like them, and wrote this post to promote their use!To make a strict table, add STRICT to the end of its definition. Like this:-CREATE TABLE people (name TEXT);+CREATE TABLE people (name TEXT) STRICT;That’s it! But what does it do?Advantages of strict tablesBroadly, strict tables help enforce rigid types, like other SQL engines do.Prevents type mismatches on insert/updateMost significantly, strict tables keep you from inserting the wrong type into a column. For example, SQLite normally lets you put text into an INTEGER column, but not with strict tables.-- Non-strict tables let you put anything anywhere.CREATE TABLE people_nonstrict (age INTEGER);INSERT INTO people_nonstrict (age) VALUES ('garbage')
3ヶ月前

Notes from June 2026
Evan Hahn (dot com)
Chicago’s weather is pretty lousy most of the year, but when it’s nice, it’s very nice. June blessed the city with dozens of idyllic days. But don’t worry—I still spent most of the time inside on the computer.Things I didI launched my first big project at Ghost: automations! It’s still in beta, but it’s one of the biggest projects I’ve led. If you happen to be a Ghost publisher, please try it out and let me know what you think!For the sixteenth issue of the Taper online magazine, I visualized time by breaking each unit into sixteenths. For example, as I write this, I’m about 6 sixteenths through the hour. Like every Taper submission, my work had to be under 2048 bytes.Links about AI ethicsGenerative AI continues to, mostly, be a force for bad in this world:“If AI is going to 10x our productivity across the board, that means that I should be able to produce the same amount of output by midday on Monday that, in the before times, would have taken all week. So can I just take Friday off?”
3ヶ月前

"Sixteenth of a year", a 1.8 KiB art piece
Evan Hahn (dot com)
As I write this, we’re about 7 sixteenths through 2026, and it’s about 14 sixteenths through the day.For the sixteenth issue of the Taper online magazine, I split time into sixteenths to think about its passage in a different way.The code, which had to be under 2048 bytes, isn’t terribly complex. It does some date math and uses a Go server for minification. If you want, here’s the unminified source code.Go check out all the other entries from this issue! My favorites include "[SIC]", “Desperate Measures from a Dying Regime”, and "(un)done".See also: my previous Taper entry.
4ヶ月前

Notes from May 2026
Evan Hahn (dot com)
My blog turned 16 this month! I did nothing to celebrate, but made some little tools and clicked some links about tech ethics.Things from me this monthI published four little tools this month:ZIP Shrinker, a web app that shrinks ZIP files with higher compression ratiosA command line tool to do (completely offline) translationOpen Link in Unloaded Tab, a Firefox extension to open links without loading thempng-cmp, a command line tool to compare PNG pixel dataI also did some work on Helmet, my open source project:After over a year of quiet maintenance, I released version 8.2.0 with some small new features and documentation updates.In a step toward dropping GitHub, I moved the docs from a GitHub URL to helmet.js.org.And like every month, I wrote a few articles at Zelda Dungeon. I don’t feel I wrote anything special this month, but my colleagues put together a feature about Zelda and mental health which was very affecting!Links to click on“The vast majority of tech workers, at least those
4ヶ月前

Make ZIP files smaller with ZIP Shrinker
Evan Hahn (dot com)
I built ZIP Shrinker, a little browser tool to shrink ZIP files. It also works with formats that are secretly ZIPs underneath, like EPUB, JAR, and many more.Try it out!How does it work?At a high level, this tool (1) re-compresses every file in the ZIP archive with higher compression (2) removes all metadata (3) removes entries for directories.Re-compressingZIP files are typically compressed with an algorithm called Deflate.There are a few tools that can re-compress Deflate data and make it smaller, usually by spending more time on the computation. I took one of these tools, libdeflate, and applied it to each compressed entry in the ZIP. I chose libdeflate because of its performance; alternatives like Zopfli can achieve marginally smaller results but take much longer.I created libdeflate.js, a WebAssembly wrapper for libdeflate, as part of this work. (I always relish my time working with WASM!)Removing metadata and directoriesEach entry in a ZIP file can contain additional metadata like
4ヶ月前