Spoken like someone who has never worked on a long-lived project. There is no beginning, middle or end. You joined when it has been around for 7 years. It needs to be around 10 more years.
Early and careful abstraction of absolutely every layer of your program is something you will always thank yourself for. If your classes only talk to interfaces at every single layer (no concrete classes talking to concrete classes, except for maybe a factory here or there to vend out said interfaces), your project will be much easier to test, refactor, and dynamically change.
Yes I find these sorts of comments as GP to be hopelessly naieve. It speaks to somebody who has never worked on a large project (think 4 teams of 10-20 developers spread across NYC, London, Tokyo, and Hong Kong) or a long-lived project (think 10 years).
That sort of minimial, incremental approach does not scale at all. Software engineering in the large requires, as you say, interfaces at every boundary and a near-religious understanding of how all the different components and boundaries fit together.
I agree, though from the other side your sort of comment does not acknowledge the fact that a lot of projects do not require that kinda of scale.
Fundamentally they are very different practice of software development and I think what OP talks about are those many cases where there is no scale need, never will be, yet we see this design approach that is suited for the type of projects you talk about.
> Early and careful abstraction of absolutely every layer of your program is something you will always thank yourself for.
If you knew what you were doing when you made those early and careful abstractions, then I agree completely (the Go standard library, after all, is a set of careful & well-reasoned abstractions). But if you made the wrong choices three years ago, because you didn't understand the problem you have today back then (either because you didn't understand the problem then, or because the problem changed), then you're going to hate yourself.
If you're attacking a well-known problem which will be the same problem you'll be attacking in a decade, then sure: early abstraction isn't premature. But how often do we do that, and how often are we exploring an unexplored problem space? At least for the projects I've worked on, each one has been terra nova.
Early and careful abstraction of absolutely every layer of your program is something you will always thank yourself for. If your classes only talk to interfaces at every single layer (no concrete classes talking to concrete classes, except for maybe a factory here or there to vend out said interfaces), your project will be much easier to test, refactor, and dynamically change.