I teach my kids that the systems they are programming should be considered onions of abstraction layers. They need to understand how to choose from among the options available at each level and to realize that those options are constantly changing.
This onion is the only way we can deal with the ever-widening diversification and combinatorial explosion of hardware platforms, communications channels, types of users, geographic dispersion, data sources, problems to solve, etc.
Improvements at one layer demand adaptations at another; accumulate enough options at one layer and you need to encapsulate them in another. And the bigger these onions get, the more leverage they provide to anyone who uses them, meaning any improvement you make to some part of the onion is contributing to solving a thousand, or a million "actual problems" simultaneously.
If solving end-user problems is "why we're all doing this in the first place," a toolmaker who can solve 50% of each of a million different problems simultaneously is contributing more than those of us who solve the remaining 50% of just one.
This onion is the only way we can deal with the ever-widening diversification and combinatorial explosion of hardware platforms, communications channels, types of users, geographic dispersion, data sources, problems to solve, etc.
Improvements at one layer demand adaptations at another; accumulate enough options at one layer and you need to encapsulate them in another. And the bigger these onions get, the more leverage they provide to anyone who uses them, meaning any improvement you make to some part of the onion is contributing to solving a thousand, or a million "actual problems" simultaneously.
If solving end-user problems is "why we're all doing this in the first place," a toolmaker who can solve 50% of each of a million different problems simultaneously is contributing more than those of us who solve the remaining 50% of just one.