> But this boils down to If you build systems using a high level of skill and foresight, it's easy to do.

Yes.

> This is of course not a tautology, but a contradiction.

It's not quite a contradiction! If you bill $1 for changing the bolt, and $9,999 for knowing which bolt to replace, this shows that the work is easy, but the experience required to make the work easy is not easy. If the master can draw it in seven strokes, but you don't see the seventy thousand strokes they did before, it looks easy, and in fact it is easy, for the master but not for the novice.

> I agree that inexperienced developers can, as it were, 'make life hard for themselves', but that's (trivially) due to their inexperience. I don't think there's a silver bullet for inexperience.

That's right. However, we can also make life hard for each other, and there are some solutions for that that are better than doing nothing.

> Over-engineering is bad, as is under-engineering. Fuzzy principles like 'YAGNI' can't be applied without skilled discernment, which means experience.

Yes. This is why we have code reviews, design reviews, pair programming, and so on, but these aren't silver bullets either and there is no silver bullet, but if these things lead to increased awareness of why and not just what and how, then we can accelerate the process of acquiring that discernment. As Dijkstra said, if it goes to the grave with you and you didn't pass it on, you didn't really do your job as a senior engineer (paraphrasing).

>> Programming is hard, but we make it much harder than it has to be by doing it spectacularly wrong in many ways, both individually and collectively.

> I think I agree with this, but it depends on specifics. What sorts of things are you thinking of?

Using the wrong tool for the job. Using too many tools for the job. Using tools that do not afford mastery, because they are too complex for anything built on top of them to be comprehensible.

This is all quite abstract. A specific example: we (the JavaScript community) had a good thing in that JS was a small, human-scale, useful and commercially valuable language with applications beyond its initial environment on the web. We got excited and built the npm package archive, and filled it up, and now we have unmaintainable, incomprehensible piles of trash piled upon trash that can't possibly be used as a foundation for anything reliable, performant, or maintainable. This is unfortunate. What's even more unfortunate is that this piled-up-trash approach still has momentum, still lets people get useful work done, and still has some value to the community. So we keep using it, and even keep piling more on. It takes considerable effort to step back from all this, take a collective mulligan, and start over with a principle of taking things away to make things better, rather than adding more hacks to hide existing hacks.

This is one example of many, but I mention this one because I was there when JS was simpler and better and I watched as we made it markedly worse. I would have recommended JS as a first language to beginners when node.js and npm were new, and I did, but I cannot now recommend them in good faith, because they have become antagonistic to quality and to mastery of the craft.