I really do think curiosity is the most important bit out of all this.<p>If I see some bit of our code doing something a bit odd, I'm nosy, I'll go and look why. Why does one of our classes use an IDisposable? Why is that property using a custom class? Why is that code using async/await when it looks like it should take nano-seconds?<p>If it's for a good reason, you'll have invariably found a gotcha, or gained a little more knowledge about the domain you code works in.<p>But surprisingly often you'll find that it's for a bad reason, or an outdated reason, or someone not really understanding how the functionality they're using works.<p>In the early days of a language/framework especially, when people really don't understand how it really works, what you see is a lot of cargo-cult code. Doing without understanding. .Net, Jquery, Ruby, Javascript, Typescript, Node, I've seen it happen many times (and of course done it myself too! I remember making loads of pointless singletons in one project a decade ago).<p>People do something because they don't have the full picture. They make up totally wrong rules like "If I add IDisposable the GC must work better as I believe IDisposable has something to do with the GC so it can't hurt".<p>A great example right now, in the .Net world, is people are littering their code with async/await. They can't understand it's making their code worse, not better. They don't understand that the performance gain is almost always negligible, but the code complexity increase is expensive.