Code always was, it's supposed to be malleable. It's why it's long been said that code is a liability, not an asset. It's the data you generate with that code that's your asset. You can always rewrite the code.
We, in general, are just very bad at letting code ossify, or for this metaphor, dry out and crumble. AI does not solve this problem and I fully expect to see situations where AI generated code becomes so hard to work with that even LLMs prefer to throw it away and start fresh again.
Working code that people pay to use is of course an asset. If it is a liability then just delete it all an have no source code an you just paid off a debt for free.
Code was malleable only to a developer with great code comprehension. In my experience, this was actually very rare. I think part of the reason is, you don't get any recognition for modifying a few lines of someone else's code compared to "I created this new library/app to solve this problem for our org!".
> Code was malleable only to a developer with great code comprehension
This used to be what being a dev was, if I recall. It's been a few years.
I think we romanticise the old days of coding now that agents are doing it.
Regarding the average developer as an imbecile was a cottage industry from Djikstra to FizzBuzz.
I romanticized even before, because there is a reason why society's view of developers shifted from geek losers to rich in the past 15 years. I remember when 15 years ago a girl told me that I'm different, because I'm not as looser as how she imagined developers.
Sure, but it was certainly a difference between those projects you authored and those you inherited, at least in time-to-productiveness.
The ability to understand and maintain inherited projects is more valuable than the ability to create new greenfield projects.
In terms of value as an income, then for a consultant this is most likely true - for staff working in a megacorp not so much.
And often, it's not the code that is the issue. You understand the code perfectly fine and can edit it easily. The main issue is always finding out the "why" so you do not remove any Chesterton's fence while coding for a new change request.
People with poor comprehension have been changing code for years, and in great numbers. Doesn't mean it goes well, mind you.
The big trick always was to limit your scope. If you can't do that or if your tooling doesn't help you with that then very quickly you will run into the limits of what you can still keep in your head.
> Code always was, it's supposed to be malleable
Yes, well-designed code is malleable to an extent when coding by hand, but even then it's an order of magnitude more rigid than when working with agents (and real-world code often ossifies, as you pointed out). Malleability comes not only from the possibility of change but also from the speed.
> It's the data you generate with that code that's your asset. You can always rewrite the code.
I like that perspective, but "you can always rewrite the code" almost never happens in real life for complex projects, and when it does, it's a huge undertaking that takes many months or even years. Malleable code makes that much more feasible, I'd argue.
Rigid implies you are trying to change something into something else in a controlled way. Eg a refactoring that does nothing but enable for a future feature. Agents does not change code to refactor anything, they write code to solve the new feature directly. And if you are good at prompting they might overwrite code that exist so that the end result looks like a refactoring. But no clay was reshaped.
I think you may be misunderstanding.
The point is that previously, changing code in a major way might take months of refactoring. Large changes were simply not contemplated unless they were justified by similarly large additional profit. Once you designed your architecture, you were pretty much stuck with it.
Now, the kinds of changes that were simply unrealistic before are now entirely realistic. A refactor/migration that would have taken 6 months before, you can now get a working version done in a day, and another few days of QA. That's what this post means -- code is no longer stone, it's clay. You can change it quickly in ways that were previous unimaginable.
This has nothing to do with the concept of code being liability or asset -- that's a totally separate conversation.
> The point is that previously, changing code in a major way might take months of refactoring.
> Now, the kinds of changes that were simply unrealistic before are now entirely realistic. A refactor/migration that would have taken 6 months before, you can now get a working version done in a day, and another few days of QA.
Significantly changing a system implementation is a function of understanding, not time.
Given a starting solution state being A and a desired functionality state of A', the tooling used to codify the A -> A` delta is largely irrelevant. Specifically, in order to successfully deliver major product realignment requires awareness of what exists currently and understanding of what needs to be.
Code is neither stone nor clay.
This is fantasy though.
The reason code takes time to change is not because changing it takes time.
You have to redo all the testing and relearn all the hard fought and underspecified lessons of the previous attempt. That's what takes the time.
I was watching the most recent Rich Hickey talk[0] and at the start, he talks about correctness and the difference between the internal machinery of your software (which can be finely specified) and handling the external world (which will always be messy).
Good Architecture will try to isolate the two. You got the internal logic which is either the business domain abstracted away. And you got the highly volatile part (request from frontend, new integration, new drivers, deps update,....).
If you've done that, migration/refactoring, unless it entails some unlikely core changes, will not take that long. It's just a matter of dropping that part and replacing it (like changing a car's brake pads or steering wheel). But the actual core mechanism will hardly change over the years.
To go with the thread flow: It's a stone core wrapped by clay.
[0]: https://www.youtube.com/watch?v=P5eO7BNyJao
ADDENDUM
In regards to separation, one of the best example in mind is the OpenBSD kernel code. The OS concepts are in /kern, while each architecture lives in /arch. There's an horizontal separation between machine independent code (core idea of Unix) and machine dependent code (The hardware platform). It can also be found in the various subsystem like audio (the concept of a sound card) and implementation like uaudio (usb interface) and azalia (Intel's HD Audio).
> AI does not solve this problem
AI absolutely solves that problem. Just about every prompt "fixes" the dried out pieces of the code. And it's only getting better at that every month.
Sometimes I feel like people are experiencing AI so differently that it makes talking about it nearly impossible.
> Finally, there is the delight of working in such a tractable medium. The programmer, like the poet, works only slightly removed from pure thought-stuff. He builds his castles in the air, from air, creating by the exertion of the imagination. Few media of creation are so flexible, so easy to polish and rework, so readily capable of realizing grand conceptual structures.... https://home.adelphi.edu/sbloch/class/adages/joy.html
Dependency is a cause of ossification.
Truly spoken as someone who has never worked with legacy code. You know, the kind that's still running Java 1.something when Java was already doing full numbered releases.
The kind that works, but everyone who knows why has left the company. The whole codebase is written in a way that makes automated testing either impossible or so time-consuming that the client will never pay for the required refactoring.
There is way too much code in the world we never were able to rewrite due to real-world concerns. There were people who had the skill, but a part of that skill came with knowing the risks of doing major refactoring to a money-generating system that is ancient, but still works.
Anecdote: I had to work with a system where the original coder (long gone) had rewritten Linked Lists with their custom solution that worked normally except the first X items were the sum, average and mean of the data. Fun times.
We can fully solve 'code' in the sense we can model every single interaction and then use that specification to produce another program that does the exact same thing, and then based on inputs, it should be possible to cull that tree of possibilities even more.
That is my hope anyway, apart from that, I do think there is an inherent laziness in business to not mess with the machine that makes money.
If you don't do the work to separate the actual specifications from what the legacy app happens to do then why are you even rewriting it?
Maybe, but I think one of the points is that the marginal cost of both understanding that legacy code base and safely refactoring it are increasingly trending down thanks to agentic coding tools. It changed the value and risk tradeoff for legacy apps, if deployed properly. There's still a lot of work (too much) to get the harness in place to make high confidence changes to legacy, critical apps. If someone makes that more automated, we'll be in a very different place for legacy refactoring and it will look a lot more like the clay molding the article discusses.
As with anything LLM-related, I feel compelled to ask, is that actually what's happening, or are they just successfully convincing their users that's what's happening? I truly cannot tell.
I'm not using any LLMs directly (my workplace still bans them in-house) and my experience on the receiving end of contractors using them is quite poor. That includes one major, "we'll replace your ancient software with shiny new stuff"... with significantly reduced capability that in turn makes everything far more difficult than it was or ought to be. The UI appears much more user friendly, but really is just broken in multiple ways where the much-patched 1980s software it replaced was user-unfriendly but largely worked.
This all could be the result of poor coding, regardless of LLM use, of course.
With this new-found capability, you can use an LLM to plan and execute some long-needed refactors, or use it to pile on new features even faster with no regard for tech debt management.
As others have said... it's a tool. A powerful tool in the hands of a wise and skilled wielder who makes planned, focused changes, or a slop-cannon in the hands of someone who is happy to churn out features with minimal understanding of context or system design.
I've been able to do relatively big refactors with great success, like porting thousands of lines of data transforms to drastically different data stores practically in one fell swoop. In the background. As I worked on other stuff.
The cost of experimenting is just mind mindbogglingly cheap now, it's really insane. Don't like the abstractions it comes up with, or think it generated a bunch of slop? Go again, who cares? With a little more steering, they'll often produce exactly what you want.
As for contracting firms, many of them were slop shops before AI, I imagine those kinds of firms are even worse slop shops now.
> I fully expect to see situations where AI generated code becomes so hard to work with that even LLMs prefer to throw it away and start fresh again.
You know, I've never thought about that. It's really interesting to consider, especially since refactoring code is now cheaper than ever.
It's literally called _soft_ware (vs. hardware).
Clod (claude?) of Clay.
> It's the data you generate with that code that's your asset.
Not sure what kind of data this refers to?
> Code always was, it's supposed to be malleable.
This. Since forever was I told that the term "software" was coined because, contrary to hardware, it was easy to change, adapt, and mold into your needs.
I'm very surprised to hear people in this day and age claim it wasn't.
> code is a liability, not an asset
This is not the case as far as accounting and the law is concerned.
[dead]