I think the main insight from "functional core, imperative shell" is more about structuring the code so as to be easy to test.
Without that structure, code tends to be difficult to test, since the impure stuff like network requests is part of the same sequence of statements as the logic you want to test. (That is: pure code is easier to test (but harder to write real programs with).. so, "arrange the code so you've got a well tested core" is a good strategy).
The nice part about the pure/functional is that you know for the same inputs, you always get the same outputs. -- I think if you want to say, "well, this stateful object is still pure (if you consider the state part of the input" then sure, I guess.
Correct. FCIS is about testing. Testing pure code is a lot easier than testing impure code, but most of what you want to implement can be done with pure code, and you can isolate the impure code to a shell that can be tested apart from your pure business logic.
LLMs are not magical tools which take slop as input, and produce well thought out documentation and tests and code as a result.
Over the last year, LLM coding agents gotten pretty good. It's no longer "if your results suck, you gotta try the latest and greatest model". You can get capable results on a wide variety of tasks, with a wide variety of models, used in a wide variety of ways.
When you’re required to approve thousands of lines a day (code you can’t possible understand), it certainly IS causing issues that didn’t exist before.
Every study I’ve seen correlates the use of AI with large increases in the number of bugs. Look at Amazon dialing back AI after massive outages. Microsoft patch Tuesday releases are bricking computers (they even managed to break notepad somehow). The rash of Facebook bugs also coincided with their move to AI. Leaks from Google have engineers saying AI either doesn’t save any time because it takes so to remote stuff or it causes breakages if they speed up.
These companies can afford to get the best devs. They have access to essentially unlimited token budgets. They have STILL fallen off a cliff in quality.
What more proof could there be that this isn’t sustainable?
A correlation-causation link between AI use and these bugs has not been established. Until it has proven to come from the region of AI-pagne, it's just sparkling enshittification.
This isn’t the human body or some other thing with billions of unknown parameters. It’s a single (relatively simple) math equation that you are ascribing tons of non-existent complexity to.
Left to its own devices, that system will result in AI autophagy (model collapse) and iterative degradation.
The only area with serious uncertainty is how humans interact, but we now have research showing humans suffer cognitive issues very quickly using AI (some studies indicate effects happen in as little as 10 minutes) with cognitive surrender being a particularly big issue.
In a lot of systems, the only new data seems to be a few brainstorming sentences (you can read slop as entropy decaying things). The AI slops that into requirements. That slop feeds into an agent which generates a bunch of “reasoning” slop, maybe compacts everything (more slop), and spins up agents that get handed slop. They then open files with who knows how many generations of slop (maybe never even touched by a human) and write out a bunch more slop (it’s ironic that humans get better the more they edit a file, but AI gets worse). That slop gets “tested” by another agent reading all the other slop and maybe all this recurses a few generations.
At the end of this AI equivalent to “the human centipede”, you get a developer who’s handed 10x or maybe even 100x more code than their brain would possible process. They are suffering complete cognitive surrender (not to mention often reaching mental and maybe physical collapse from the workload and stress). They don’t understand the system and rubber stamp it so they can move on to the next 50 PRs of the day.
From start to finish, it’s 100% entropy outside a handful of lines worth of human input.
Many people predicted bugs and even discussed entropy issues before AI coding was popular. The buggy mess timing aligns not only with AI adoption, but happens to each company ramping up as they ramp up AI usage.
This is like seeing Einstein’s predictions happen, but arguing he can’t prove correlation/causation. What evidence would you actually accept that is feasible to study?
So you're saying that LLMs let you accrue technical debt faster? I suppose that's like the fact that living on payday loans let you accrue monetary debt faster.
I think if you're on a team that cares about quality, LLMs can help you write quality code faster.
If you're on a team that's mindful about technical debt, you can have make practical trade-offs for velocity now at the expense of paying off technical debt later.
And if you're on a team that's unable to care about code quality ("I gotta merge this code now!"), then you can write mountains more code than you can understand.
I think it's true that good, well tested code will have higher code coverage than crappy code.
But, above a certain point (which will vary from codebase to codebase), unit tests aren't meaningfully increasing confidence that the code is working.
I'd recommend focusing instead on the code being written in a pure 'functional core, imperative shell' to the extent that's possible. For that pure/functional part, 100% code coverage is attainable (& so not worth remarking on). For the impure parts, unit tests are probably using "mocks" just to get the code to compile anyway.
> Sure, there is still use for language expertise, but not enough to get excited over new concepts and ideas.
Programming and learning new things can still be fun in the era of agentic coding.
With LLMs, I get to quicky ask: what would this look like? Why do it that way? If you suspect that the LLM isn't doing it the right way, you can still investigate that yourself.
e.g. the other day, https://rhombus-lang.org/ was mentioned on HN. With LLMs, the cost for trying this out is practically much lower.
Yep, learning new things is amazing now. Just today I went through some really crappy slides, just dropped them to gemini and asked for elaboration. It saved me hours of figuring the shit out the old fashioned way.
> Now, if you can steer an LLM reasonably well, you can quickly build an MVP that goes well beyond your own understanding of the implementation.
Pre-LLM, I'd distinguish between e.g. "I know Python" and "I know this codebase". So if I wrote a codebase in Python I'd be familiar with it, if someone else wrote a codebase in Python I'd be familiar with the Python. -- An LLM coding agent can give a codebase in Python very quickly.
With a newbie, they'd be familiar with neither; but an LLM coding agent can give them a full solution written in Python.
I'd say that this power from LLM coding agents blurs the distinction, in some sense. But to an extent it's always been the case that abstractions allow programming without a full understanding of everything down to atoms.
People 'can' learn faster than they used to. But I'd think those who are curious to learn will be able to have better results than those who only have a shallow understanding.
This prioritises accuracy/history of what happened, but this has significant disadvantages and practically no advantages (other than "accuracy of what happened".
There are cases where you really do want an append-only leger, where tampering with history is malicious. -- But, generally, it's preferable to be presented with something tidy.
From some other comment in this thread, I get the impression it's possible to re-present a set of changes in a clean/tidy way? That seems a better way of putting it. "You can still have a clean view into a set of changes while preserving an accurate history of what changed".
What's hard to understand is why you'd be against the idea of tidy communication/presentation of changes in the first place.
Can you help provide examples from your development experience where "knowing the accurate history of what happened" was a very big advantage, to the extent where not having this knowledge would have made things very difficult?
Here a developer thought that redis would be a good add to the stack, so we decided he should try. It turned out that it didn't fit, mainly because it needed to touch code in more places than anticipated. We went back to starting point, but the project now carries a "no more redis/cache attempts before reading this one, please" fossil. New attempts can't say "oh, I didn't know this was attempted before".
With git, this kind of experiment would be hidden with a "reset hard", and probably will happen again when people forgets, someone says "didn't we try that a year ago?" but we have no records.
This is very helpful in small private teams, not so much in biggest teams (kernel), pass-by PR environments (github), or public CV-oriented repos (no mistakes allowed there, only pretty linear timelines).
> I wonder what use case there would be to checkout the same branch in multiple worktrees.
I've run into it when I've wanted to checkout that branch (to try running code there, or view a file, or rebase it, or whatever) and there's already a worktree checked out.
This is more like treating worktrees as "lightweight clone of the repo checkout out at some dir". (If it were a separate clone, it wouldn't be an issue to have the same branch checked out in two places).
The linked post is not that long. The readme in the linked project happens to be longer, but it's clearly because the author put tables of keymap bindings in the readme.
It's what I'd hope a well-written readme should look like, I think.
Without that structure, code tends to be difficult to test, since the impure stuff like network requests is part of the same sequence of statements as the logic you want to test. (That is: pure code is easier to test (but harder to write real programs with).. so, "arrange the code so you've got a well tested core" is a good strategy).
The nice part about the pure/functional is that you know for the same inputs, you always get the same outputs. -- I think if you want to say, "well, this stateful object is still pure (if you consider the state part of the input" then sure, I guess.
reply