Another aspect of writing code is to think about future speed readers. Can your code be skimmed and understood on a cursory level?
For example code a “user data cache” with lots of user concerns and people will be reading that code a lot.
Code a “generic cache” and test the hell out of it and it’ll never need to be read (or rarely)
There will need to be code that deals with users but it can interact with the cache so where business logic ends and caching begins is obvious.
Then repeat: how can you split the user code up into generic concepts? Users vs. roles vs. credentials?
While it is important to separate concerns where applicable (might be user related functionality and caching) generalization most of the time just adds complexity.
I am not advocating making “unnecessary” abstractions.
I’m not even advocating abstracting from the get go: sometimes you need to see the messy to appreciate the abstracted.
This is modulo all common sense trade offs!
I'm often astonished by the stuff people don't see on their screens when helping them debug something. Replying to "how did you know?!" by pointing to the edge of the screen where some small blob went from green to orange or to red is something that happens more often that I'd expect.
How we learn and the speed at which we read (how we chunk the information together - and how as an author we put together information to be readily chunkable) are very closely tied together.
Edit: hold on! I think i got lost in the double-negatives, and I agree with you. :)
Right, reading twice as fast increases the "WTFs per minute" metric by 4x: 2x because you get through twice as much, and 2x because you understand half as much.