My first thought was that the “ground beneath your feet”, that might move around more than you initially expected, would be the libraries and dependencies you call on; other people’s code that your code relies on. You might see old methods become deprecated in ways that break your use of them—or new methods introduced that you want to switch to, for efficiency gains or other reasons.
Which can be mitigated by some forethought to put in a layer of abstraction that wraps around the library, so that you only have to change how you call the library in the wrapper, without changing the rest of the code. But can also be taken too far (if you put a wrapper around all kinds of really basic functions, just creating extra cruft for no good reason).
Can also suffer from “leaky” abstractions, if your wrapper makes assumptions about the library that don’t hold up, or if the code calling the wrapper needs to still know about the underlying library to work right. Not sure quite what the analogy to a building foundation would be there—I guess if you thought your big concrete slab was trustworthy as an immovable foundation, but then it turned out that big concrete slabs on top of dirt behave importantly differently to big concrete slabs on sand.
My first thought was that the “ground beneath your feet”, that might move around more than you initially expected, would be the libraries and dependencies you call on; other people’s code that your code relies on. You might see old methods become deprecated in ways that break your use of them—or new methods introduced that you want to switch to, for efficiency gains or other reasons.
Which can be mitigated by some forethought to put in a layer of abstraction that wraps around the library, so that you only have to change how you call the library in the wrapper, without changing the rest of the code. But can also be taken too far (if you put a wrapper around all kinds of really basic functions, just creating extra cruft for no good reason).
Can also suffer from “leaky” abstractions, if your wrapper makes assumptions about the library that don’t hold up, or if the code calling the wrapper needs to still know about the underlying library to work right. Not sure quite what the analogy to a building foundation would be there—I guess if you thought your big concrete slab was trustworthy as an immovable foundation, but then it turned out that big concrete slabs on top of dirt behave importantly differently to big concrete slabs on sand.