I definitely agree with that, and I think a preference for more verbose code is actually very compatible with this idea. Verbosity is not the same as over-complicating or over-abstracting things. In my experience a lot of the time it's actually the drive to avoid verbose code that causes these problems in the first place.
For instance, you have two functions that are similar but with some important difference, and the developer decides that anything that resembles duplication is bad and refactors them into a single abstraction. This type of thing can cause much more harm than just leaving in a little bit of verbosity by keeping the functions independent of each other.
If so, then by keeping them separate, you introduce the risk that you would forget to update the other. Using a single function and calling it twice, even with different parameters, is a way communicating that it's important that the semantics be tied.
If a change in one wouldn't imply a change in the other, then you really have two separate semantic roles being played that happened to resemble each other in implementation - harmless incidental duplication.
If there's a really obvious answer to that question, then great. But often the answer is "sometimes" or even "most of the time". We train most developers beginning even in intro-level programming classes to err on the side of deduplication and over-abstracting in these cases, but the longer I've been working as a developer the more I have come to think it's better to err on the side of allowing some duplication except in the most clear cut of cases.
Clearly defined purpose for each layer when doing abstraction.
Verbosity and simplicity.
And NEVER EVEN try to be smart. In two weeks you will forget how the 'smart' solution works and have to spend x2 time changing it.