Full Width [alt+shift+f] Shortcuts [alt+shift+k]
Sign Up [alt+shift+s] Log In [alt+shift+l]
3
Life in Code: A Personal History of Technology is a book of essays by Ellen Ullman. In the book, Ullman laments the bad parts of computers and the internet. These systems eroded privacy, deepened income inequality, and enabled the rise of modern fascism. And they were built by a tiny subset of people—young men, mostly white and Asian, mostly wealthy—to the exclusion of almost everyone else. Despite all this, she maintains a hopeful fascination with technology. Perhaps humanity can use these tools as part of a better world. I share this sentiment, I think. Many of the stories are old by Silicon Valley standards, but they feel prescient. The book is filled with ideas that could be written today, if you modernized a few incidental details. These are my notes and quotes from the book. “Outside of Time” (1994) Ullman on the idea that low-level development is more respected: “If you want money and prestige, you need to write code that only machines or other programmers understand.” Oh, and...
2 weeks ago

Improve your reading experience

Logged in users get linked directly to articles resulting in a better reading experience. Please login for free, it takes less than 1 minute.

More from Evan Hahn's blog

UI tip: maybe don't round percentages to 0% or 100%

In short: maybe don’t round to 0% or 100% in your UI. I am not a UI expert. But I sometimes build user interfaces, and I sometimes want to render a percentage to the user. For example, something like “you’ve downloaded 45% of this file”. In my experience, it’s often better to round this number but avoid rounding to 0% or 100%. Rounding to 0% is bad because the user may think there’s been no progress. Even the smallest nonzero ratio, like 0.00001%, should render as 1%. Rounding to 100% is bad because the user may think things are done when they aren’t, and it’s better to show 99%. Ratios like 99.9% should still render as 99%, even if they technically round to 100%. For example, in your UI: Ratio (out of 1) Rendered 0 0% 0.00001 1% 0.01 1% 0.02 2% 0.99 99% 0.99999 99% 1 100% Here’s some Python code that demonstrates the algorithm I like to use: def render_ratio(ratio): if ratio <= 0: return "0%" if ratio >= 1: return "100%" if ratio <= 0.01: return "1%" if ratio >= 0.99: return "99%" return f"{round(ratio * 100)}%" This isn’t right for all apps, of course. Sometimes you want to show the exact percentage to the user, and sometimes you don’t want the app to appear “stuck” at 1% or 99%. But I’ve found this little trick to be useful.

6 days ago 4 votes
Takeaways from The Economist's style guide book

I’ve been trying to improve my writing so I read Writing with Style, the Economist’s style guide book. Here were my main takeaways: Use short sentences. They’re more memorable. They’re easier to read. They’re generally easier to write. Colons are for setup and delivery. They describe them as “dramatic”. One thought per paragraph. The paragraph is a “unit of thought”, according to this book and to H.W. Fowler. Sometimes, you have a one-sentence paragraph because the thought fits into a single sentence. Prefer simpler terms. Use “get” instead of “obtain”, “make” instead of “manufacture”, or “give up” instead of “relinquish”. Ask if you ever use the word when talking to friends. And don’t soften difficult topics: “a poor person has no more money, opportunity or dignity when described as ‘deprived’, ‘disadvantaged’ or ‘underprivileged’.” The right word can eliminate others. More specific words let you “dispense with adjectives and adverbs entirely. Consider the difference between ‘walk’ and ‘strut’, or ‘say’ and ‘murmur’.” Find big-picture issues with a “reverse outline”. When editing, they recommend extracting the main point from each paragraph. This can catch structural issues. Watch out for differences between English dialects. I knew about a lot of these, like how I’d spell it “color” and a Brit would spell it “colour”. But I didn’t know about “quite”: in American English, it’s a synonym for “very”; in British English, it can mean “fairly”. (The book failed to mention other dialects of English, to my disappointment.) There were things I didn’t like about the book. It seemed allergic to whimsy. A lot of its rules felt arbitrary. The Economist writes for a different audience than I do. But these disagreements helped me clarify my own writing style, so they were still helpful. I think my writing is better as a result of this book. I recommend checking it out!

a week ago 2 votes
Notes from March 2025

Here’s a little roundup of things I’ve done in March. Also see my entries from February and January. Words I wrote in March I published a few blog posts this month: “Why ‘alias’ is my last resort for aliases” explains why I prefer defining scripts over shell aliases. I’ve been doing this for years and finally wrote about it. Response to this post, at least on Lobsters and Hacker News, was mixed. It was on the front page of Lobsters for awhile, but only briefly peeked into the bottom of the HN front page. Some people agreed with my idea and some did not. I also learned a few things about aliases from comments and emails, and have a few edits to my dotfiles I’d like to make. “Filling in the gaps of the internet” describes a philosophy of mine: if I ask a question, can’t easily find the answer, and then eventually find the answer, it’s my duty to publish something. I’ve done this many times on my blog. Some of those posts have gone nowhere, but others are very popular, and others have even been turned into books! I read Beyond Measure: The Hidden History of Measurement and posted my notes. The book shows how measurement, which might seem dull, is linked to culture, scientific advancement, and bloodshed. Speaking of measurement, I found out about Rink, a unit-aware calculator. I love it. I published a little cheatsheet showing how to do various conversions and calculations. I wrote “An ode to my favorite mobile game”, Forward: Escape the Fold. It’s one of the best video games I’ve ever played, and certainly my favorite mobile game. Speaking of video games… I’m now a writer at Zelda Dungeon! For any fellow Legend of Zelda fans out there, I also joined Zelda Dungeon’s volunteer writing team this month! I’ve been a ZD reader for years and it’s surreal to see my work on the site. This month, I published my first few articles: “What Will the Next Zelda Game Be Like? Let’s Consider What We Know So Far” rounds every little tidbit we know about the next Zelda game. Spoilers: not much, but we know a little! “Former Nintendo Marketing Manager Shares Inside Look at Zelda’s Notorious NES Commercials, Early Prospects of a Zelda Film, & More” summarizes an interview with Gail Tilden, a long-time marketing manager at Nintendo of America. I recommend checking out the original interview or just reading my Zelda-focused summary. I also wrote entries for their “Daily Debate” feature, such as questions about the Switch 2 and comparing Ocarina of Time and Breath of the Wild. Everyone at Zelda Dungeon is really kind. It’s a dream to be writing for a blog I’ve read for years, and about my favorite series! If you’re my biggest fan and want to see everything I publish there, see my author page or subscribe with RSS. Tech news I read The Legend of Zelda is important, but so is the real world. There was plenty of tech news this month, including American war plans being illegally discussed in a Signal chat. Here are a few things that I read that weren’t major headlines: Technology is not neutral or apolitical, and Techdirt wrote about this: “when WaPo’s opinion pages are being gutted and tech CEOs are seeking pre-approval from authoritarians, the line between ’tech coverage’ and ‘saving democracy’ has basically disappeared. It’s all the same thing.” Mozilla doesn’t want their money from Google to dry up, which makes sense. I liked this take: “it’s certainly not healthy for those small independents to depend for their survival on the good will of companies like Google.” 18F, an American government technology group, was shuttered this month. They put up a letter saying, “We’re not done yet.” SocialNet is a tool that scrapes over 200 services, like TikTok and Facebook and GitHub and Lobsters and eBay, for surveillance purposes. I don’t use social media much, but I looked through the full list and have used about a third of them. “Apple restricts Pebble from being awesome with iPhones” complains about all the ways Apple makes it harder for third parties. Things I read about LLMs (mostly negative) The internet has no shortage of opinions about generative AI. A few from this month: "‘Wait, not like that’: Free and open access in the age of generative AI is a great essay that covers a variety of topics: AI’s “vampiric relationship with the commons”, the value of the commons, and much more. Probably my favorite read of the month. There’s a lot of discussion about the carbon emissions of AI. “Tech and the climate crisis” convincingly argues that we should be focusing on more important problems, like disrupting the status quo. Last month, someone wrote “LLMs can’t dream” in a comment I read. “The Empty Promise of AI-Generated Creativity” extends that idea, arguing that AI-generated narratives have “a distinctive blandness that comes from averaging thousands of human voices”, and that this is a “fundamental” property of generative AI. Hugging Face’s co-founder argued something similar: “we don’t just need a system that knows all the answers, but rather one that can ask questions nobody else has thought of or dared to ask.” I saw LLMs described as a “charismatic technology”: “something that under-delivers on what it promises, but promises so much that the industry still leverages it because we believe it will eventually deliver on these claims.” ProPublica talked about how they use “self-hosted open-source AI” in their reporting. “Here’s how I use LLMs for programming” blog posts have been a recent trend, and I liked seeing how they’re used in other contexts, especially important ones like this. “Please stop externalizing your costs directly into my face” (reasonably) rants against how LLM scrapers make it harder for smaller websites because of all the traffic. This isn’t the first time I’ve seen complaints like this. It makes me think of projects like Anubis, which (try to) block AI scrapers. More links from March Finally, here are a bunch of miscellaneous things I found this month. From “Nobody Profits”: “The Internet delivered huge value but no profit, and that’s why it was good. Suddenly we had all these new powers. Then people figured out how to monetize it. It was a race to extract every tiny bit of value, and now we have today’s Internet.” (Whenever I despair about the state of the web, I browse Marginalia or Wiby.) Watched a video showing how to build a UI layout algorithm. I think this quote epitomizes the video: “just because someone explains something in a complicated way doesn’t mean it actually is complicated.” Super approachable and informative, and clearly more clever than the layout algorithm I wrote for Signal calls back in 2020. Firefox 136 added a bunch of new features, including native vertical tab support. My cynical view: they released this to distract from their worrying privacy policy changes. My charitable view: this is a great feature and I love it. Frieren: Beyond Journey’s End is a top anime on MyAnimeList for a reason: it’s really good! I’m no art critic so I won’t describe it well, but the show beautifully explores themes of mortality, regret, and time. Its pacing is unusual: leisurely but engaging. I finished the first season this month, and was completely wowed. Highly recommend watching. Found this directory of people’s private planes, so you can see where Musk, Bezos, and others are jetting off to. I briefly used Subversion to resurrect an old half-built prototype I started in 2011. I imagine some of my readers don’t even know what Subversion is given Git’s ubiquity. Running svn checkout felt like dusting off an ancient grimoire and babbling a basic incantation. YouTuber J.J. McCullough uploaded another “flag mysteries” video last month. This one might be his best yet. This Washington Post column points out that the American Bureau of Labor Statistics distinguishes between the term “computer programmer” and “software developer”, which I didn’t know. (I didn’t love the article—it points out “apocalyptic and astonishing” job losses for programmers, then points out that software developers are actually doing fine, then points out that the terms are “almost interchangeable”—but I liked the one detail in it. Also, I don’t trust the Washington Post’s opinion section.) But I thought it was interesting that the BLS sees a distinction where I see a synonym. I love Alex Goldman’s (relatively) new podcast, Hyperfixed. I listened to an episode from February that was right up my alley, talking about hex color codes and license plates. If you’re like me and love hex codes and license plates, I’ve got the episode for you! Vim tip I learned this month: type 50% to go to the middle of the file. TypeScript is rewriting their compiler in a faster language. I liked this summary of why they chose Go. PCs for People is an American charity that repurposes “retired” computers. If your office is looking to get rid of a bunch of old computers, consider giving them a call. Hope you had a good March.

3 weeks ago 3 votes
Cheatsheet for Rink, the unit-aware calculator

Rink is a unit-aware calculator for the command line and your browser. I’ve been wanting something like it for years! Here’s a Rink cheatsheet I made for myself. I hope it’s useful to others! Basic conversions Rink can do a bunch of basic conversions, such as converting Fahrenheit to Celsius or kilometers to miles. Basic unit conversions: > 10 pounds to kilograms approx. 4.535923 kilogram (mass) > 32 degF to degC 0 °C (temperature) Byte conversions: > 1 KB to B 1000 byte (information) > 1 KiB to B 1024 byte (information) See “How big is a kilobyte?”. Work with ratios: > 0.25 -> percent 25 percent (dimensionless) > 25 percent 0.25 (dimensionless) > 100 meters * 25 percent 25 meter (length) Convert currencies To convert euros to Indian rupees: > 1 EUR to INR 94.5045 INR (money) By default, conversion rates update from the internet once an hour. You can configure this feature, including disabling it. Numeric suffixes You can avoid typing a lot of extra zeroes with helpers like “billion” and “thousand”: > 1 billion / 1 million 1000 (dimensionless) > 1 billion kilograms / 1 million pounds approx. 2204.622 (dimensionless) Base conversions (hex, decimal, binary, etc) You can take a number in one base (e.g., base 10) and convert it to another (e.g., hexadecimal). To convert a decimal number to hex, use base 16 or the hex alias: > 420 -> base 16 1a4 (dimensionless) > 420 -> hex 1a4 (dimensionless) Convert a decimal number to binary, use base 2 or the bin alias: > 420 -> base 2 110100100 (dimensionless) > 420 -> bin 110100100 (dimensionless) You can also use “classic” hex, octal, and binary literals: > 0x45 69 (dimensionless) > 0o644 420 (dimensionless) > 0b1010011010 666 (dimensionless) Estimate download speeds This shows off the unit-aware features of Rink. To estimate download times: > 100 GB / 25 mbps 8 hour, 53 minute, 20 second (time) Time math Time math is the real reason I downloaded Rink. Convert a time to another time zone: > #2025-04-20T18:09 America/Chicago# -> "Africa/Lagos" 2025-04-21 00:09:00 WAT > #01:23# -> "America/Sao_Paulo" 2019-01-23 05:23:00 -02 > now -> "Asia/Yangon" 2019-01-23 17:26:00 +0630 Compute time deltas: > #2025-01-23# - #2024-02-10# 49 week, 5 day, 0 second (time) > #2025-01-23# - #2024-02-10# -> day 348 day (time) > #2025-01-23# - #2024-02-10# -> hour 8352 hour (time) > now - #2025-01-01# -> day 109 day (time) Math with time deltas: > now + 3 days 2020-01-26 01:23:00 +00:00 > now - (four score years + seven years) 1933-01-22 23:40:20.182200 +00:00 (92 years ago) Remember that months and years are weird (at no fault of Rink). Compare Rink’s default year and month units to alternate ones: > 1 year -> days approx. 365.2421 day (time) > 1 calendaryear -> days 365 day (time) > 1 month -> days approx. 30.43684 day (time) > 1 lunarmonth -> days approx. 29.53058 day (time) Fun, weird stuff This stuff isn’t useful to me, but it’s cool that Rink supports it. It has support for a ton of interesting units, most of which I’ve never heard of: > 2 halfnotes to wholenote 1 wholenote (musical_note_length) > 1 horsepower to donkeypower approx. 2.982799 donkeypower (power) > 12345 furlongs / fortnight approx. 2.053091 meter / second (velocity) > lettersize to inch^2 93.5 inch^2 (area) > volume of uranus / volume of moon approx. 3111.849 (dimensionless) The “buttload” unit isn’t yet supported, but it seems like it will be in a future version. Rink is so cool!

a month ago 3 votes

More in technology

Fire In The Hole, We’re Breaching The Vault - Commvault Remote Code Execution (CVE-2025-34028)

As we pack our bags and prepare for the adult-er version of BlackHat (that apparently doesn’t require us to print out stolen mailspoolz to hand to people at their talks), we want to tell you about a recent adventure - a heist, if you will. No heist story

9 hours ago 3 votes
DOGE Worker’s Code Supports NLRB Whistleblower

A whistleblower at the National Labor Relations Board (NLRB) alleged last week that denizens of Elon Musk's Department of Government Efficiency (DOGE) siphoned gigabytes of data from the agency's sensitive case files in early March. The whistleblower said accounts created for DOGE at the NLRB downloaded three code repositories from GitHub. Further investigation into one of those code bundles shows it is remarkably similar to a program published in January 2025 by Marko Elez, a 25-year-old DOGE employee who has worked at a number of Musk's companies.

22 hours ago 2 votes
You Need Customers to Succeed in Small Business

For your small business to survive, you need customers. Not just to buy once. You need them to come back, tell their friends, and trust you over time. And yet, too many small businesses make it weirdly hard to talk to them. Well, duh, right? I agree, yet I see small businesses fumbling this over and over. All the attention when discussing business is about giant corporations. Whether they’re selling servers or vehicles or every product under the sun, millions of dollars pass through their doors every day. Yet it is folly to apply the methodologies of giant companies to our small businesses. It sounds obvious, but I constantly see small businesses making it hard for customers to get in touch. If a customer does get through the “contact us” gauntlet, that small business often uses needlessly complicated enterprise software to talk with customers. Small businesses don’t get the spotlight, but they are the engine of the economy. To wit, in the United States: 99.9% of businesses are small Nearly half the private workforce is employed by small businesses They generate over 43% of the country’s GDP And beyond the stats, small businesses are who we turn to every day: your corner coffee shop, your local cleaner, your neighborhood software team. And don’t forget that every big business started small. Small businesses are the genesis of innovation. We all need small businesses to succeed. Most small teams aren’t trying to become giant corporations. They want to make a living doing work for a fair return. Many of them work hard in hopes of moving the needle from a fair return to a comfortable life, and maybe even some riches down the road. Yet it’s amazing how often it’s forgotten: you need customers to succeed. Success in small business starts with human conversation. While talking effectively with your customers does not guarantee success, it is certainly a requirement. Here’s what that looks like: a customer has a question and your team responds kindly, clearly, and quickly. Or sometimes your team wants to reach out with a question for a customer. It’s a simple, human interaction that cannot be done effectively by automation or AI. It’s the air your small business is breathing. Starve that air, and everything else suffers. Your product or service is almost secondary to building a healthy relationship with each of your customers. Big business doesn’t operate this way. We shouldn’t expect it to show us how to build real relationships. We’re doing our best here at Good Enough to build healthy, happy customer relationships. Whenever you write to us about any of our products, someone on the team is going to reply to offer help or an explanation or an alternative. Fact is, if you write to us about anything, we’re going to reply to offer help or an explanation or an alternative. As an online business, we’re talking with customers primarily over email. For us, Jelly makes those conversations easy to have—human, not hectic. Actual customer support is remarkable. Actual, healthy human relationships are important. Actual customer conversations are a key to small business success. Choose your actions and tools accordingly. If you liked this post, maybe you’ll like Jelly, our new email collaboration app for small teams!

19 hours ago 2 votes
Eurorack Knob Idea

[Hardware] An idea for knobs for synthesizers.

4 hours ago 2 votes
Vote for the April 2025 + Post Topic

Poll will only be live for 3 days, so vote while you can.

21 hours ago 2 votes