Full Width [alt+shift+f] Shortcuts [alt+shift+k]
Sign Up [alt+shift+s] Log In [alt+shift+l]
3
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...
3 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 "Life in Code: A Personal History of Technology"

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 these prestigious and lucrative jobs are primarily held by young men. And these boys impart their ideas into the systems they build: As the computer’s pretty, helpfully waiting face […] penetrates deeply into daily life, the cult of the boy engineer comes with it. The engineer’s assumptions and presumptions are in the code. “Come in, CQ” (1996) Learned about The WELL, an online community that’s been around since 1985. I also learned that the elm email client was succeed by Pine, another tree name. Pine was then succeeded by Alpine, another piece of wordplay. Quips like this resonate with me: I do believe that the operational definition of a thing—how it works—is its most eloquent self-expression. A lot of user interfaces seem to encourage immediate action: Although we seemed to be delaying, prolonging the time of imagination, the email was only rushing us. I read a message. The prompt then sat there, the cursor blinking. It was waiting for me to type “r” for “reply.” The whole system is designed for it, is pressing me, is pulsing, insisting: Reply. Reply right now. Even though I meant to hold the message awhile, even though I wanted to treat it as if it were indeed a “letter”—something to hold in my hand, read again, mull over—I cannot resist the voice of the software, which was murmuring, murmuring: Go ahead. You know you want to. Reply right now. A poignant paragraph about the demise of Morse code: The [Morse] code had a personality to it, a signature in the touch and rhythm on the key. For Turner, the signature’s origin was no mystery: “It’s coming from a person’s hand.” Makes me think about the things you trade for convenience, and the information that’s lost when you measure. “The Dumbing Down of Programming” (1998) This essay was originally published in Salon. I learned what “BIOS” stands for: Basic Input/Output System. Never thought about it before! To anyone who laments the messy design of modern terminals: […] we build our computers the way we build our cities—over time, without a plan, on top of ruins. This was written in 1998 and sounds similar to modern opinions about LLMs: My programming tools were full of wizards. Little dialogue boxes waiting for me to click “Next” and “Next” and “Finish.” Click and drag, and—shazzam—thousands of lines of working code. No need to get into the “hassle” of remembering the language. No need even to learn it. It is a powerful siren-song lure: You can make your program do all these wonderful and complicated things, and you don’t really need to understand. […] This not-knowing is a seduction. I feel myself drifting up, away from the core of what I’ve known programming to be: text that talks to the system and its other software, talk that depends upon knowing the system as deeply as possible. What a sweet temptation it is to succumb: Wizard, dazzle me. Ullman explains the risks of these systems. When something inevitably goes wrong, you may be powerless to debug it. I liked this bit which acknowledged the tradeoffs engineers have to make: We were reminded that software engineering was not about right and wrong but only better and worse, solutions that solved some problems while ignoring or exacerbating others. “What We Were Afraid of As We Feared Y2K” (1999—2000) This essay was heavily adapted from a 1999 Wired article. This essay made me think I should read an entire book about the history of Y2K. (If you know of a good one, let me know.) “The Museum of Me” (1998) Related to an earlier point about the developers encoding their worldview into the software they build: I have long believed that the ideas embedded in technology have a way of percolating up and outward into the nontechnical world at large, and that technology is made by people with intentions and, as such, is not neutral. The author talks about how the Internet glorified self-service, and only the very rich could afford human help. Here’s one of those prescient passages. Remember that this was written 27 years ago: But now, without leaving home, from the comfort of your easy chair, you can divorce yourself from the consensus on what constitutes “truth.” Each person can live in a private thought bubble, reading only those websites that reinforce his or her desired beliefs, joining only those online groups that give sustenance when the believer’s courage flags. “Fiber Optic Nights” (1999) You might be skeptical of the tech world. But when you’re surrounded by the techno-optimism of Silicon Valley, it’s hard to resist: At this stage of inebriation, I can’t resist the atmosphere of wild optimism. I let myself fall under the delicious cloud of dreams: the great global internet that will change human life—indeed, change humans themselves. Ullman laments how San Francisco’s diversity made way for tech startups, a “colonization” I noticed myself when I lived there. She expands on this much more in the final essay. And another sentence talking about how engineers only value “hard” engineering: Any serious software engineer would scoff at my dragging in philosophy, the fuzz of the humanities. “Off the High” (2000) Sad that this is still true 25 years later: Maybe what has put the damper on this year’s conference is that, after the Canadians pass their law, the United States will be the sole nation in the highly industrialized world without legal data-protections. Or maybe it’s the fact of being in Canada, where everyone who is an American knows that, on crossing back into the United States, they will lose their constitutional right not to be subjected to unreasonable searches. “Programming the Post-Human” (2002) This essay originally appeared in Harper’s Magazine in a slightly different form. Comparing Moore’s Law to software development: […] there is no Moore’s Law for software. On the contrary, as systems increase in complexity, it becomes harder—very much harder—to write reliable code. This essay is mostly about AI, and what it means to be alive and conscious. I think this quote succinctly sums up the whole thing: The more I thought about it, the more I decided that huge swaths of existence would be impenetrable—indescribable, un-programmable, utterly unable to be represented—to a creature that did not eat or shit. “Dining with Robots” (2004) Ullman rejects the often-used comparison that programming is like a recipe. Could a computer understand many of the subtle, and perhaps ancillary, parts of cooking? (To be fair, I’m a bad cook, so I probably can’t either.) The world resists the rigidity of software: The world, the actual world we inhabit, showed itself to be too marvelously varied, too ragged, too linked and interconnected, to be sorted into any set of frames or classes or problem spaces. Reminds me of a point repeatedly made in Beyond Measure, another book I took notes on. Computers are described as “fast, efficient, untiring, correct, standardized, organized”. “Close to the Mainframe” (2014) Ullman describes the intoxicating feeling of being sucked in by a tricky bug. This is one of the sweetest parts of computer programming! The Party Line (2015) Ullman talks about a small farm being affected by technological “efficiency”. This farm needed to start putting their milk in something called a bulk tank, or be left behind. Technology promises efficiency, but it also messes things up: Bulk-tank collection was surely more efficient [than] picking up individual cans. Consumers might benefit from the lower costs of production. It was technology at what it does best: standardize and homogenize and monetize, create efficiencies in sales and markets and distribution chains. It was also technology at its worst. The coming of the bulk tank was another of those ruptures in society. Yet this one did not widen the scope of individual freedoms. The tank would effectively drive the small family dairy farm out of existence. Programming for the Millions (2016) Ullman describes a programmer’s job as that of a “translator”. That’s sometimes how it feels! It reminds me of “meeting the computer halfway”. I liked this bit about breaking down the divide between humanities and software: I dare to imagine the general public learning how to write code. I do not mean that knowledge of programming should be elevated to the ranks of the other subjects that form basic literacy: languages, literature, history, psychology, sociology, economics, the basics of science and mathematics. I mean it the other way around. What I hope is that those with knowledge of the humanities will break into the closed society where code gets written: invade it. Boom Two: A Farewell (January 2017) The final essay really laments how San Francisco has changed. This quote sums it up best: The startup culture has overtaken San Francisco. It was once a place for kids running away from home, where people in their teens and early twenties came to get away from the lives they were supposed to lead but didn’t want to, to be gay or bisexual or other combinations of sexuality, all looking for some version of the old, wild, open San Francisco: the Beats, hippies, free love, the gay revolution. Yet nothing abides forever, and now we live in a city whose former identities, however mythical, have been swept away. A new wave of youthful seekers has come a-searching for yet another mythical San Francisco: a place where dreams of founding a successful internet startup are born, and fulfilled. There’s also a short passage about someone pitching their tech as being easy-to-use, using a phrase like “Even Grandma can use it.” Ullman (rightly) calls this out as sexist and ageist. I used to say stuff like this and am embarrassed by that! I’ll end with a quote about tech saviorism: How far away was and is the true work of creating a more egalitarian world, the slow, hard job of organizing, the hours of contentious community meetings: the clash of need against need. Only those who work close to that ground, and take the code into their own hands, can tell us what technology is good for.

2 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