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.
Suppose you have an empty plot of land and want to build a house. To someone without a civil engineering background, it may be tempting to just start building right on top of the bare soil.
However, this isn't The Sims. If you build your house on top of bare soil, you will likely face serious problems within a few years.
Why? Well, the short answer is "differential movement". But to explain what that means, let me first take a step back.
The goal for structural engineers: when you put something on the ground it should not move. In everyday life this is easy; objects are small and time horizons are short. If I'm at the park and I put my phone on the ground next to a tree, the soil isn't going to shift and cause a massive crack in my phone. But if I build a 200,000 pound house directly on the ground and wait a few months, I might not be so lucky.
The first thing to understand is that the ground isn't a solid, contiguous piece of matter. It's actually more like this:
Or maybe this:
This was an aha moment for me. Before watching this video, which I'm basing a lot of this section of the post on, my naive model of the ground was more like this:
That model serves me well when I put my cell phone down on the ground at the park, but it wouldn't serve me well in my hypothetical future as a home builder. The whole is composed of parts, and those parts can move independently of one another.
So what, exactly, actually causes the movement of these soil particles? Well, the weight of the home is part of it, but in practice, a lot of the issue is related to water. Soil expands when wet and shrinks when dry. Freeze-thaw cycles are especially bad. Tree roots can be a pain.
Anyway, why is this soil movement a problem? Well, take a look at this:
I don't know how to explain it well, but such differential movement can cause cracks.
To mitigate these risks, instead of building houses directly on soil, we build them on foundations. Something like this:
Or this:
When the soil moves beneath the foundation, the foundation will hopefully remain in tact. This allows us to accomplish our goal: when you put something on the ground it should not move.
Of course, even with a foundation, your luck will only last so long. Father Time and Mother Nature are a formidable duo.
If you want your foundation to last you 500 or 1,000 years instead of 75 years, that's probably doable — you can build something deeper and more solid — it's just going to cost you. Like most things, you'll need to make decisions about trade-offs. These decisions will depend on considerations like project size, time horizons, and budget.
What about software engineering? What would it mean to start building on top of "bare soil"? What sorts of "cracks" might form? After how long? How damaging would they be? What would a proper foundation look like? Which types of foundations are appropriate for which types of projects? And how long can a foundation realistically last?
As the idea for this post was brewing in my mind, I was hoping to discuss all of these questions in depth and say a bunch of smart and insightful things about them. But to be honest, that would be a bit beyond my pay grade. I'm a solid software engineer but I'm no John Carmack.
So then, I am pivoting to a more How To Write Quickly While Maintaining Epistemic Rigor type of approach. I'll describe some thoughts I have on some of these questions, and I'll leave it to people in the comments to continue the conversation. I know a lot of people here have software engineering backgrounds.