First job had me using a programming language I wasn't super familiar with and trying to add a feature to a codebase 100s of KLOC, all written by other people. Definitely a sink-or-swim moment. My skills of reading and navigating the dreaded Other People's Code were all honed over the next dozen years.
That being said AI is a lot better at reading code than I am, as demonstrated by its ability to find incredibly subtle bugs in huge codebases. So I'm not even sure those code reading skills are all that useful now. When I have to review somebody else's code I get more mileage from pointing an AI at it and asking targeted questions like "how does this handle when a Foo's approval is revoked" than reading it myself line-by-line. I'm not saying I never use those reading skills but the ability to get the big picture, chase down deep callback chains, know where to look... those skills are likely to atrophy.
It's like using GPS vs. knowing the roads as well as a cabbie. GPS gets you pretty damn far for zero effort.
It's an important skill to learn, as a lot of software developers enter the market as "selfish", thinking they should understand and / or own all code, and if there's too much code or too many other people, they will advocate for microservices so they can once again own their slice of code.
But that's coding; software engineering is coding at scale, over time, and for the last two you need a different (albeit complementary) skillset of both hard and soft skills (hard skills being reading / understanding / reasoning about code, soft skills being letting go of your own ego and giving constructive feedback)
But building mental models based on data and communications from others is one of the most valuable problem solving and communication skills there is in business, precisely what Carson is getting at in his essay.
There's a perhaps subtle difference between possible and viable.
It’s often hidden behind the syntax and implementation because of the layers of abstraction. A single operation (semantic wise) may be scattered over many statements, and some definition may be important in several subconcepts. It helps to be familiar with various technical concepts as possible. basic data structures like lists and trees, more advanced concepts like scheduling and concurrency, as well as platform concepts like files, process, networking,…
Why? Because they are implementation details that distract from the main conceptual model. It’s like how OpenBSD handle device discovery and configuration. Once you know that it’s a tree, you just need to remember how you build a tree and then most of the code are obvious. You can then discern the traversal stuff from the actual device configuration easily and know how to focus your reading.
Taking a problem or a wanted behavior and dissecting it down to logical manipulation is hard for those people. They can go down one or two layers but then they got lost while building the necessary abstraction. You can observe it pretty much in real time as they’re losing track of assumptions for the current context. Thinking that way is a skill and once you can do it, reading and writing code is pretty much effortless.
Both learning to write and learning to read is merely a proxy of learning to think. Doing one while not doing the other is handicapping yourself for no reason.