19,821 karma · joined February 2, 2009
It's like a CO2 scrubber that runs on coal.
It'll be interesting to see if this is sustainable. I could see it going both ways, and I honestly don't know which is most likely.
I'm a heavy AI user and haven't written code by hand in a long time (and probably won't until Advent of Code, honestly) but I'm already sick of people using AI to replace code at things that code excels at and AI is no better at, just slower and more expensive.
It isn't just driven by the AI companies, either. I've already seen it internally, with developers who need diagnostic tools creating Claude skills, and in the excitement of adopting AI, barely noticing that they're incredibly slow, expensive, unreliable, and even slow to create compared to the script or diagnostic endpoint they would created in the past. And they're surprised to learn that Claude skills suffer from bitrot and cross-repo dependencies just like traditional software: somebody's Claude skill fails because it wasn't updated to match changes elsewhere, and it takes much longer to realize that a conversation with Claude is going wrong than if a script or an endpoint returns an error.
When code is the best solution, by all means use AI to write it! But don't use AI instead when AI isn't fit for purpose.
At least then the squashed messages were usually pretty decent. But then people started using AI (or AI started using people) to create absolutely massive commit messages that are impossible to skim in git blame and overall very bad for human consumption.
AI has made massive strides in virtually every other way. Why do they continue to write in a wasteful, human-hostile way?
I think we'd have to be be very naive not to suspect that this is intentional. AI companies have a stated goal of replacing humans in the software development process, and they're actively making the process itself inhospitable for humans.
They are injecting massive amounts of text into their customers' development process, which then becomes tokens that their customers will then pay them to process over and over again. It's like a CO2 scrubber that emits CO2.
First principles are an illusion. Good engineers make strategic choices of the supposed "first principles" they apply, and on a particularly difficult problem, they may iterate through multiple options before discovering the "first principles" that yield a good solution.
Engineers that take first principles seriously and try to use them to guide their decisions discover that correct-sounding first principles tend to work in some contexts and fail in others. Then they go one of two ways responding to these failures.
One way is to blame the context. My favorite example of this is a project where a consultant writing a Java web service struggled for months to get Hibernate to emit queries than ran efficiently on the company's Oracle database. Pressed by management to write the queries by hand, the consultant insisted that using Hibernate was a non-negotiable "best practice." Eventually the manager grepped the logs, identified twelve distinct queries that the service needed, and tasked the Oracle admin with optimizing them, which took less than an afternoon. The consultant still pushed back against using the hand-tweaked queries, saying that if the answer emitted by Hibernate didn't run efficiently, then the database schema was wrong and needed to be fixed. This was not the right response when the database in question was the beating heart of a hundred million dollar tech company and was optimized to handle massive transactional workloads, and the consultant was struggling to write a simple web service for internal users.
The second way is to push your first principles to higher and higher levels of abstraction to make them less context-dependent. They update "Use Hibernate for database access" to "Use whatever database library or framework makes it possible to achieve the best results with the least developer effort" and eventually resort to something like "do whatever achieves the best outcome measured by its impact on what is important to you at the time."
I think a better approach is to collect a toolkit of potentially helpful principles and develop understanding of when each principle tends to be helpful.
> The final, particularly strong, objection from the tech community is "don't touch my stuff". People get angry when they have worked hard to get their desktop environment just as they like it and something changes to disrupt that. "And I get that. As I said before, I don't want to change everything." But the world is changing, "and we need to grow our way gently into some new things."
Unproven innovation shouldn't be forced on people who don't want it. It should start by proving itself with people who have an appetite for novelty and opt into experimentation. Winning their interest will be a lower bar anyway, generating better constructive feedback on half-baked ideas, with less risk of backlash. Then, as ideas are improved and vetted, they can work their way into the mainstream.
The fact that they're not describing any such process, and instead announcing that they're coming straight for the "don't touch my stuff" crowd, makes me very wary that they think the hardest part of UI innovation is forcing people to use it against their will until they accept it.
It's basically the work you get from a smart, diligent person who is oblivious to any shared goal and approaches every assignment with a CYA attitude.
I once tried to explain a pointless debate over the definitions of "acceptance testing" versus "regression testing" to a non-tech person, and they said that was the most relatable thing I'd ever told them about my job.
As for basic toiletries being locked up, I've encountered that in other big cities, too. I had to find a Target employee to liberate dandruff shampoo for me in Brooklyn, and while I was wandering the aisles looking for someone, it did occur to me that Amazon could deliver to my hotel.
Also speaking as a cyclist: do you even expect them to be responsive to your presence? I've learned to think of them like they're trains. Their path and timing isn't influenced by my presence in the slightest.
If a car driver changes lanes right at me, I think, that careless asshole! But if a bus comes over into a lane I'm riding in, or if it pulls away from a stop and forces me to hit my brakes or enter another lane, I don't even register it as a mistake anymore. It's just the way buses work and something I have to be ready to react to. Thankfully their lateral movements are slow and smooth.
Unfortunately, when they deliver, they use brand-new bags, and they don't accept them back for reuse, so a lot of them get thrown away after a single use.
I worked in a company where this happened, and it wasn't pretty. Product managers used their experience and seniority to intimidate junior engineers and exert control over project management of engineering projects, which they predictably used to move as much work as possible to post-launch, including testing and security. They also gaslit junior engineers into agreeing that issues with contradictory or impossible product asks could be figured out later, leading to software getting released to customers that fundamentally could not be made reliable, performant, or even secure.
Even after the entire company went on site visits where customers told us they weren't using any of the features released in the last year because they were all buggy, and the only information they wanted about upcoming releases was assurance that their use cases wouldn't be impacted, product still kept claiming that the time it took to release new features was the biggest problem facing the company and kept fighting back against engineers who said we were in a quality crisis and desperately needed to make time for better testing and design.
The only thing that can shield you is good engineering management. Weak management will end up getting rolled by product and start promoting the bad behavior that product insists on. At that company I had a boss whose attitude towards us was "engineers in a startup should make decisions independently and stand by their work" but made sure engineers felt unsafe making engineering decisions that product wasn't happy with, likely because they felt unsafe themselves.
As a consumer, the errors that AIs make are more than an annoyance. I have yet to meet an AI phone assistant that can do anything more than an explicitly programmed phone tree, and several, including the one for the pharmacy I use, that do far less. They are undoubtedly much more expensive to create and test.
Clearly there's a bubble going on, and unprincipled people chasing funding and promotions as usual, but why are companies like CVS paying more to get less?
I think it is literally to waste our time. It's one more layer of defense to stop you from talking to a person.
There are two big wins in health care. One is to increase the scope of health care that gets paid for. More and more expensive treatments, to bring the money in. The second big win is to stop people from getting treatment. Deny coverage, confuse them and wear them out with bureaucracy, and in this case stop them from talking to an expensively educated human pharmacist. That's what an AI does better than a phone tree, because it more effectively creates a sense of helplessness and valuelessness in the customer.
Expanding the scope of care you're entitled to and then fighting against your ability to get it isn't a contradiction any more than it's a contradiction when a person breathes in and breathes out. It's two synergistic parts of a system whose goal ultimately has nothing to do with health care.
Some of those things are specific to web applications. Others are not. It's fine for web-specific logic to be tied to all of the shared assumptions of a web framework, but application logic should not be. As the architecture evolves, the application logic may need to be run in other architectural contexts: as a message consumer, inside an orchestration framework, etc.
That's one of the most painful things about PHP. Entire businesses get built around business logic in PHP backends, and then when you need to execute that logic in a different architectural context, every line of it has to be rewritten, because it's too much work to extricate it from the context of serving web requests.
If you are designing your framework to contain application logic, then it should look ahead to the possibility of that logic being used in a different architectural context. It should facilitate and encourage writing application logic that is agnostic of the web context. Otherwise you're encouraging people to repeat the mistake of PHP all over again.
I've been in situations where I was sure this was true. I've also been in situations where the person claiming it simply refused to become competent in the language, framework, or persistence technology that the system was built on.
Also subjective: "The business needs a capability the current code was never shaped to grow into." Most of the times I've heard this brought up, it's not that you need a re-write, but you need a re-architecture. Often the existing system can continue to do its job as it always has, but in a new architectural context. Or 90% of the code can stay the same, while the application it runs in is changed, for example from a web service to a Kakfa consumer. (This is why it's so important to avoid languages and frameworks that are tightly bound to an architectural choice.)
I also think it's too adversarial. The author's claim, "If you genuinely believe something others don’t, that’s not a debate to win. That’s an edge," is not very persuasive, because you communicate far more with teammates, bosses, and subordinates than with enemies and competitors. Most of the people you communicate with on a day-to-day basis are people who can be dealt with more profitably through cooperation.
"You Can Only Change Yourself" is another far too absolute conclusion. You change and are changed by everybody you come in contact with. Every conversation is a chance to influence someone. If you can't make them see your point right away, you can sow the seeds for a future insight. Or you can clarify why you disagree. You can change their mind from "this person doesn't understand the problem" to "this person cares about an aspect of the problem that I don't think is primary."
I think the author should broaden their idea of what can be achieved in talking with someone they disagree with. It won't help them win arguments, but it will help them reap more benefit over time.
You may have worked with people whose meaning of "code quality" encompassed things that you found inconsequential and a waste of effort. They may have even told you that if you didn't care about those things, then you didn't care about code quality. But that's not true. It only meant you disagreed with them about what code quality is and how to recognize it.
You draw a distinction between aspects of code that tend to lead to better outcomes and aspects of code that don't matter. You say you know what tech debt looks like. When you look at a codebase, you have opinions on where time should be spent to improve it. "Code quality" is shorthand for the heuristics underlying those opinions.
Instead of accepting that other, possibly dumber people get to define what code quality is, own your own definition of it and use it when you communicate with other people.
Also, this argument is some grade school smarty pants "I'm too smart to show my work" bullshit:
> And because the interviewer can’t distinguish “skipped steps due to incompetence” from “skipped steps due to operating at a higher cognitive level,” they default to the interpretation that protects their ego.
I thought the days of hiring toxic "so smart I can't communicate" superstars was over?