> when we push down a "bump" of complexity in one place, seventeen bumps at least as large can crop up elsewhere.
I think you've taken the metaphor about a waterbed and design advice a bit too literally. :)
When you push complexity down in one area and it pops up in another, there's no guarantee that it's of the same overall magnitude, as it would be in a real waterbed. Sometimes it's larger, and sometimes it's smaller.
The same idea applies to whether we should all write assembly or use a higher level language to accomplish our computing needs. We push down the complexity of knowing exactly what the processor is doing at any one moment for a easier to manage overall view of what we want to accomplish. Overall, the net effect is a lessening of complexity for most people, but for those that want or need to know exactly what is going on, there more complexity. Still, overall I think the net effect is less complexity for most people, vastly outweighing the time and effort a few put into figuring out why something isn't as expected.
On the other end of the spectrum, using a dynamically typed scripting language might save people a lot of time initially, or when prototyping, or on smaller programs, but as those programs become larger, the lack of constraints (which provide a small but immediate complexity hurdle) can build up and overwhelm a large project that might otherwise had an easier time if some more constraints were required along the way.
No one tool or paradigm is perfect for every task, and we should not expect one to be. We don't usually commute in dump trucks, and we don't usually haul lots of debris in compact cars. I see no reason why it should be any different for programming languages. Sometimes all you need is a 10 line bash script, and given that information, I doubt there's a huge level of complexity that's going to rear its head later because I didn't write it in some lower level language.