The problem with the article is that it's two arguments pretending to be one.
The first argument is about people. People romanticize the flaws of their tools, turn vim macros into a personality, and mistake the feeling of cleverness for output. Fine. True. Bill is correct that a lot of tool evangelism is tribal signaling dressed up as productivity advice. However, people join these tribes because they get benefit from it. If the tool wasn't meeting their perceived needs, they wouldn't be passionate.
The second argument, the one in the title, is about tools: that being invisible is what makes a tool good. That one is fundamentally wrong, IMO.
Halfway through, Bill admits the invisibility test "is a personal one." Which means: a tool is good when it disappears for you. Sublime is invisible to him because he's been at it for fifteen years. On day one it was not invisible to anyone. In fact, I remember buying a book and reading it back in the day about how to get better at using Sublime. So "good tools are invisible" reduces to "good tools are tools you've already mastered." That's not a claim about tools; rather, it's a claim about experience. Every powerful tool is bad to the novice and invisible to the expert. So I'll categorize this one as a veiled tautology.
Then there's the metric. Bill's "honest test" is wall-clock time and mistakes made. Anyone who's less familiar with a tool is going to make more mistakes up front. I have a couple of professional-grade sanders that I've used for some projects around the house, and because I use them infrequently, I tend to make mistakes when I get started since it's not my core competency.
The right question for a power tool isn't how fast you did the routine thing, it's what became possible that wasn't before. Git is not invisible to anyone, ever, and it's the most successful version control system ever built, for better or worse. Of course, lots of people also think Git is bad, so I'm not making any particular claims on that front, but it did manage to reach a local maxima that led people to jump ship from SVN et al. SQL has been the standard for fifty years and is famously brutal to master. A profiler demands your full attention every time you open it. These tools are good because they expand the frontier of what you can express. A tool that makes the impossible merely hard beats a tool that makes the easy invisible. Bill's metric scores the median task and is blind to the edge, which IME is where I end up spending more of my time as I grow as a software developer..
The configurability section is where the essay argues against itself. Bill's fix for "highly configurable" cop-outs is "good defaults, plus escape hatches for the rare cases." But the escape hatch is the whole problem with his thesis. The moment a tool has escape hatches, the knowledge to use them is valuable, and the tool isn't invisible even to him. He wants the power and wants to disown the learning it costs. You don't get to do that. The escape hatch and the learning curve that leads to it are the same object. He even admits it. In the learning-curve section he concedes a steep curve "could absolutely be a cost worth paying" if the payoff is real productivity. That's the entire counter-thesis. So I'm not really sure what point he's actually trying to make with this article besides that you should have good defaults for tools.
Author here: yeah the end result is that you wouldn’t actually want to do it in practice. Who wants to build a load of linear algebra into GHC, after all? But it was pleasing to show that you could make the algorithm subcubic if you really wanted. to.
I think something that's probably under appreciated if you don't read/write Kanji– bad penmanship is incredibly hard to read due to the complexity of the characters. Good penmanship is extremely valued in Japan, so that need for precision tends to bleed over into an overarching valuing of stationary and related accessories.
Author here: I think you are projecting quite a bit. We do in fact hire a lot of people who maintain things, and even pay quite a lot for OSS development on things like the compiler and libraries we care about. But we still have business objectives to achieve, and sometimes it makes more sense to write things that better suit our needs.
Author here: I have a bunch of drafts that I haven't gotten around to publishing for quite some time, and I'm on parental leave, which affords me a little more time than usual to get things published. I don't have a lot of additional ideas left in the tank.
I'm not really sure why you'd say that OpenAPI isn't a JSON Schema document: there are published JSON Schema files on the official OpenAPI website.
See for example:
I set up spec-kit first, then updated its templates to tell it to use beads to track features and all that instead of writing markdown files. If nothing else, this is a quality-of-life improvement for me, because recent LLMs seem to have an intense penchant to try to write one or more markdown files per large task. Ending up with loads of markdown poop feels like the new `.DS_Store`, but harder to `.gitignore` because they'll name files whatever floats their boat.
To be fair, I absolutely would take ocean liners for this purpose if such a thing existed.
The closest that you can get on this front is basically seasonal route switches for cruise liners. The thing is, cruise lines price gouge on WiFi, so I'm not really able to work while taking the slow route, and I'm also having to pay food, lodging, etc.
The latency itself / limited freedom for a week or two, I don't mind. But it's the other expenditures and tradeoffs that are rather hard to stomach.
I mean this nicely, I don't really feel like anything on the landing page besides one paragraph is actually helpful to readers understanding what problem you're trying to solve.
I think it'd be useful to focus on this more:
> Voiden turns your API definitions and docs into dynamic, purpose-built interfaces — no fixed UI, no rigid templates. Everything is composed in one place and rendered down to Markdown, tailored to the API it serves.
We have a pretty limited set of abstractions that are used throughout. We mostly serve web requests, talk to a PostgreSQL database, communicate with 3rd-party systems with HTTP, and we're starting to use Temporal.io for queued-job type stuff over a homegrown queueing system that we used in the past.
One of the things you'll often hear as a critique levelled against Haskell developers is that we tend to overcomplicate things, but as an organization we skew very heavily towards favoring simple Haskell, at least at the interface level that other developers need to use to interact with a system.
So yeah, basically: Web Request -> Handler -> Do some DB queries -> Fire off some async work.
We also have risk analysis, cron jobs, batch processing systems that use the same DB and so forth.
We're starting to feel a little more pain around maybe not having enough abstraction though. Right now pretty much any developer can write SQL queries against any tables in the system, so it makes it harder for other teams to evolve the schema sometimes.
For SQL, we use a library called esqueleto, which lets us write SQL in a typesafe way, and we can export fragments of SQL for other developers to join across tables in a way that's reusable:
select $
from $ \(p1 `InnerJoin` f `InnerJoin` p2) -> do
on (p2 ^. PersonId ==. f ^. FollowFollowed)
on (p1 ^. PersonId ==. f ^. FollowFollower)
return (p1, f, p2)
which generates this SQL:
SELECT P1., Follow., P2.*
FROM Person AS P1
INNER JOIN Follow ON P1.id = Follow.follower
INNER JOIN Person AS P2 ON P2.id = Follow.followed
^ It's totally possible to make subqueries, join predicates, etc. reusable with esqueleto so that other teams get at data in a blessed way, but the struggle is mostly just that the other developers don't always know where to look for the utility so they end up reinventing it.
In the end, I guess I'd assert that discoverability is the trickier component for developers currently.
I work on one of the largest Haskell codebases in the world that I know of (https://mercury.com/). We're in the ballpark of 1.5 million lines of proprietary code built and deployed as effectively a single executable, and of course if you included open source libraries and stuff that we have built or depend on, it would be larger.
I can't really speak to your problem domain, but I feel like we do a lot with what we have. Most of our pain comes from compile times / linking taking longer than we'd prefer, but we invest a lot of energy and money improving that in a way that benefits the whole Haskell ecosystem.
Not sure what abstractions you are wondering about, though.
I lost my 3 1/2 year old daughter to sudden illness about 10 months ago. Be gentle to yourself and your family. There will be times where you aren’t actively feeling the grief, but they pull you into theirs or vice versa. There will be times where your love and grief for your lost child will make it easy to forget to cherish the loved ones in front of you.
As you figure out how to live life from here– may you find a path forward that is healthy, loving, and beneficial for you and those you care about.
The writing has been on the wall for 5+ years that government bodies would eventually legislate this, even for casual observers. If these auto manufacturers as industry insiders couldn’t plan ahead to handle this outcome, it sounds like they might deserve to be unseated.
I lost my 3 1/2 year old daughter to sudden illness several months ago. So many dreams left our family that day. Now it is up to those of us left behind to pick up the pieces.