Communicating early and often is a great and easy hack:
“In the end, write the docs you want to write. If no one reads them, or if readers find they are out of date, then consider not writing them next time. But don’t let anyone shame you into wasting time. The question is not, “Do you have documentation?” but rather, “Do you communicate clearly?”” (Kent Beck, The Documentation Tradeoff)
“Write documentation” is a tidy but unsubtle maxim. “Tell people what you did” and “help people use your software for the right thing” are better starts. Of late, “invest in written documentation for onboarding humans and agents” is an even better suggestion.
As long as you’re telling people that your thing exists, here’s when you should use it, and here’s how to use it, your documentation bases are covered.
Backyard Coffee And Jazz In Kyoto, Japan:
One of the things I read about while getting ready for our vacation in Japan were these famous tiny businesses: bars or izakayas with four seats, narrow little bookstores or record shops in people’s houses or the bottom floors of small buildings, hyper-specialized or themed bars owned by one passionate guy. (There’s one that’s chock-full of Star Wars memorabilia, for example.)
Ain’t this a friend of the gestalt? I’m daydreaming of how to run a pop-up software and coffee shop in my driveway, whilst somehow steering clear of neighborhood associations and zoning regulations. Maybe more of a lemonade stand than a “shop”. 😉
Exit Codes Are Having a Moment
LLMs (and agent coding tools in particular) love a fitness function. Give them a tool that indicates success or failure and they’ll go to town. Compiler errors, linter warnings—they love that stuff.
They also seem to love deleting failing tests—maybe they’re more human than we’d like. 😅
Never before has the exit status of Unix commands been so important—the clarity of errors, logging messages, and progress displays are all suddenly crucial. Well-written text, whether it’s a prompt, error, or informative log message, nudges LLMs towards the right next step just like it would for a human.
Any task with a decent fitness function—an LLM will handle it soon. Currently, they’re limited by human response times and gumption. But once we’re confident enough in their performance and the safeguards we’ve put up, a lot of them will be out there, just doing stuff and starting tasks based on what they predict needs doing. Wild times ahead!
Differential Coverage for Debugging. Take a failing test. You have no idea where the underlying issue might be. The system you’re working with is possibly deep, wide, and eldritch.
Your move:
- run the tests and capture code coverage without the failing test
- run the tests and capture code coverage with the failing test
- diff the line-by-line code coverage(s) to see which lines are executed in the failing case only
- eliminate further red herrings by mental elimination
Very clever! Via Thorsten Ball.
So your estimates were wrong
AKA “Help! I estimated a project and hit every branch falling down the surprises tree.” A shocking turn of events that definitely has never happened to any of us.
Don’t worry too hard when it turns out estimates weren’t accurate. They were optimistic guesses based on incomplete information and optimism that everything would go right—which it rarely does.
Do communicate to your stakeholders. Tell people whose work depends on your project about delays as soon as you know. Communicate now instead of waiting for the next scheduled update.
Don’t let your team think they have failed. If they executed well but surprises came up, tell them so explicitly. If they aren’t executing well, address that separately.
Do re-evaluate your plan with fresh estimates. If the deadline is fixed, cut scope. You can’t count on catching up by working smarter or having better luck.
Don’t ask people to work harder or longer to catch up. There’s no catching up, only keeping pace, reducing scope, or slipping the deadline.
Take an album track, in this case Daft Punk, deconstruct it, and then reconstruct from scratch in Ableton? That’s a cool hack.
I must admit something: while I consider Daft Punk’s first two albums absolute masterpieces, I’ve never been a huge fan of their guitar tones—especially their later collaborations with Nile Rodgers.
I disagree about Nile Rodgers! The thin-ness of his sound is what makes him distinctive. Chicken grease chords, in a different context.
I was talking to a pal about how some software developers are able to operate in a sort of timeless way. If contemporary tech, the stuff that made “tech people” the antagonist, is on one end of the spectrum, these developers are all the way over on the other end.
Picture a sleepy strip mall: grocery store, clothing store, paint store (why is there always a paint store?), and then, improbably, a software store. Inside, a proud but humble proprietor.
“What do you have for sale?”, you ask.
“One application, available on two or three platforms, you can buy ‘em all for less than $99”, they reply.
“You got anything else?”
“Nope, just this one program.”
Maybe you buy it, maybe you ask a few questions. Either way, the owner heads back to the workshop and keeps at their thing.
It makes an okay living. There are a couple of other people back in the workshop, helping to fix bugs, add minor new features, and keep things moving along. But it hasn’t grown to planet scale, doesn’t require astronomical growth to make payroll and pay holiday bonuses.
I’ve conveniently left out all the other small business things they have to do: accounting, marketing, so many kinds of insurance, budgeting, etc. Small businesses are all alike in that way.
It’s really great that the curious shop in the strip mall of the web, the personal website, continues to forge ahead. Maybe you call it a blog, a webring, a portfolio site, whatever. It’s still out there, doesn’t need astronomical growth to satisfy end-game finance or investors. It just is.
Another month, another Cars and Coffee event. Honestly, 75% of it was Porsche 911s of all vintages. But, I tried to work cars with other names or numbers in there too.
Experience the Rennbow.
Lovely, nostalgia. A friend’s dad had one of these leviathans back in the day.
As adventure Porsches go, this one is delightfully fitted and unique.
Porsche police cars, they were a thing.
I will always abide a Talladega Nights reference.
Porsche Heritage examples are not cheap, but they are tasteful.
Anyone miss running Linux in the 1990s/2000s and leaving a visualizer, xscreensaver
, or some kind of demo running while working on other things? Nostalgia is a heck of a thing. 😆 Improbably, Apple Music still has something close to Winamp/XMMS visualizations.
Maintain fewer and smaller backlogs
Easy advice to give, tricky to implement. Sometimes it’s effective, sometimes it’s a wash. Like rearranging for the sake of rearranging. But when it is effective, it creates mental space. And sharpens the skill of editing.
I have entirely too many items in entirely too many lists. De facto backlogs. Watch laters, read laters, tasks, notes with “TK marks”, boards holding dozens of ideas that would be nice to flesh out, someday…
All those “maybe somedays” present a non-trivial mental burden. Is today the right day for one of them? Will these lists ever get shorter? … Were it only that just the right action, supporting material, and mindset arrived all at the same time!
This is about organizing and cutting, not productivity. It may sound like weird tricks for squeezing the last bit out of every hour, but it’s not. It’s about developing the ability to do more of the good stuff so you can keep energy in reserve for when it matters.
A lot of the thinking about how to maintain a great system of lists, tasks, emails, notes and supporting material is crafting a DO NOT ERASE system for that one Truly Awesome Idea. Trouble is, they save too many Just Okay Ideas that crowd out the Truly Awesome Ideas.
Our brains have so many ways to erase an idea. Sleep consolidates memories, sometimes indiscreetly. We say something true or brilliant but have to move on to the next calendar event or get back to our routine before we can write it down. Or we simply walk through a door. Suddenly the idea is gone. Memory consolidation is our brain’s editing process. And mostly, it works!
Offloading mental burden to lists is a great hack, on balance. But develop and sharpen your brain’s natural forgetting process too. Every idea can’t be a winner.
On one hand, there’s the classical music catalog mode of blogging. This is a bookmark, that’s a note, a photo here, a link there, an essay when I’m feeling ambitious. Étude, sonata, variations on a theme. Framing the writing by its scale and shape. A taxonomist’s delight.
Then there’s the Jack White sort of blogging: here’s a thing, I made it. The edges weren’t worked down too much, the roughness is still there. It preserves the energy and spirit of the idea more than it tries to explore the idea to its logical end. Better to cut ideas too soon than coddle them.
Both work! Blogging is a big, weird tent.
I miss writing “DO NOT ERASE” on whiteboards when a collaborator and I finally succeed at capturing the mental or visual model of a problem or its solution.
It’s like writing “a good thing happened here today” on the whiteboard.
Close second place: the act of crossing an item off your to-do list, particularly one on paper.
What’s a high-level language? Is it Java, Go, and C#? Or is it Ruby, JavaScript, or Python? Where does Swift go?
It’s all a matter of perspective. To a kernel developer who thinks about bytes on a wire or spinning a disk to read a file, git
is incredibly high-level. 🙃 To a Smalltalk developer, files on disk are low-level (I assume).
Anyone telling you otherwise, including past or future Adams, is making a no true Scotsman argument.
📺Currently watching:
- The second (and final) season of Andor was spectacular. The best Star War of the past ten years, IMO.
- S3 and S4 of Slow Horses continue to delight. Capable but slovenly Gary Oldman is a great character.
- I’m surprised how much I look forward to The Studio every week. Highly recommended, even if Seth Rogen isn’t your thing.
- S4 of Hacks plays up tension between the leads more than I’d like. Otherwise, the writing and performances are excellent.
- Reserving judgement on S1 of Murderbot. The first episode did not grab me, but the second was an improvement.
- Upcoming: Not sure how I feel about The Bear. But, my feelings won’t change how award shows go, so maybe I should just go with it. 🤷🏻♂️
The web (and blogs) are free to be weird! Experiment on structure. Don’t feel constrained or normalized by the forces of engagement, algorithms, or profitability. Do your own thing.
A personal website brings flexibility for presentation. Today, you may create a chronological blog; tomorrow, you can revamp the whole website and turn it into a carefully curated knowledge garden. Today, you can design a static website (like this one); tomorrow, you can evolve it to an interactive experience.
– Candost Dagdeviren, On Owning a Website
In other words: you can just do stuff. It’s great.
1990s “alt” culture was wild. You could throw an obscure t-shirt on, watch a lesser-known or (future) cult-classic movie, and that was a whole starter personality.
“Oh yeah, I’ve met that guy Adam with the Citizen Dick shirt who really likes My Blue Heaven and Army of Darkness.” 🙃🤦🏻♂️
Whilst editing yet another newsletter on building with AI and Claude gave me this feedback:
Consider replacing “slopping out code” with a more specific term like “generating excessive code”
Apparently, Monsieur Model does not like how I refer to its art! That’s a little sensitive for a billion floating-point numbers masquerading as a French man in a trench coat. 😛
…having an LLM chat running in a terminal session (optionally accepting pastes from another LLM or watching for instructions from special comments in your source tree) is a major shift in how we relate to writing code. … Working this way, it’s easy to get down a rabbit hole of machine-generated code and lose track of either the system changes or the feature you’re trying to build up. There’s plenty of room for UX improvement. But, it’s an intriguing preview of how we might build software in the future.
Regardless of how sensitive or sycophantic models may be, there are practical options, whether you find these things charming or off-putting, to learn how to work (“collaborate”) with models.
Ed. All Beatles/Joe Cocker references in this newsletter and blog are hand-crafted with genuine human intelligence. We take pride in our musical allusions and would never consider outsourcing them to other humans or human-like statistical models. That is our quality promise to you, the reader!
Of all the hype I’ve read about AI, none of it has suggested that they will make estimating software projects a thing of the past. If they aren’t going to eat software estimates, I guess we’re going to have to strap in.
The good news is:
- Delivering software reduces the demand for estimates. The faster you can deliver software, the less you will need estimates.
- Estimating software as a list of tasks scored by effort and variance conveys the most important information required for good-faith use of estimates.
- Planning out a project by developing an estimate, rather than just hacking it out, is a way of developing software and enough of a creative effort that you might enjoy it more than sitting in meetings and updating budget spreadsheets.
— Make peace with estimates and get good at system design along the way
I finished this newsletter and asked myself, “Do I like estimates now?” I may not like them deeply in my bones, but I definitely changed my mind about them! In particular, looking at estimates as part of the creative process of designing, building, and delivering software is a useful perspective shift.
Back to the implied hype-question, “Will LLMs eat software estimation?”, I think the answer is no. Language models can’t really generate new ideas or information. Even when vibe coding, language models are reassembling existing ideas (e.g., their training data) in somewhat novel ways. They don’t generate new information, particularly in the Claude Shannon sense of the term.
Even if LLMs could generate novel information, estimates are painful when they create schedule risk (i.e., hard deadlines) rather than discover uncertainties and hedge against surprises. Language models can’t slop their way out of social, human problems.
I’ve noticed an uptick in writing about human thought processes using the language of machine learning and neural networks. Jargon-y phrases like “improve your mental search space” or “if at first you don’t succeed, improve your gradient descent”. (I only made up one of these sentences!)
Normally, I’m all about this kind of metaphorical bridge from one domain to another. But in a lot of these cases, I feel like more direct language would benefit both the discourse on language models and using them to approximate human intelligence.
The people who make LLMs have little discernible interest in cognition itself. Some of them may believe that they’re interested in cognition, but what they’re really focused on is product — that is, output, what gets spat out in words or images or sounds at the conclusion of an episode of thinking.
While it’s spectacular that science has found success in modeling human intelligence with matrix multiplication, I think the humans engaged in science would benefit by avoidance of reducing human thought (intelligence, emotion, art, the whole gamut) down to GPU-friendly arithmetic.
A lot of critics think I’m stupid because my sentences are so simple and my method is so direct: they think these are defects. No. The point is to write as much as you know as quickly as possible.
— Kurt Vonnegut
Thorsten Ball’s tutorial on building agents only takes an hour or two to work through. It’s an excellent read for audiences of all technical acumen.
It’s not that hard to build a fully functioning, code-editing agent.
It seems like it would be. When you look at an agent editing files, running commands, wriggling itself out of errors, retrying different strategies — it seems like there has to be a secret behind it.
There isn’t. It’s an LLM, a loop, and enough tokens.
After you’ve dabbled a bit with vibe coding tools, there’s no better way to wrap your head around vibe coding than to build it for yourself. There’s no magic, even if you don’t know Go!
If you’re handy with Ruby, you can easily compress the ideas therein down to about a hundred lines of code.
class ReadFile < RubyLLM::Tool
description <<~DESC
Read the contents of a given relative file path. Use this when you want to see what's inside a file. Do not use this with directory names.
DESC
param :path,
type: :string,
required: true,
desc: 'The relative path of a file in the working directory.'
def execute(path:)
File.read(path)
rescue StandardError => e
{ error: e.message }
end
end
RubyLLM is a fantastic library. Nearly all the ideas in the tutorial are concise abstractions. Recommended.