Unjustified Abstractions, Premature Abstractions

Reading on posts of Jonathan Blow and John Carmack, I think I managed to become still little better on programming. From now on I refrain from doing premature and unnecessary abstractions.

Premature abstractions are programming structures that have been introduced before they're justified. Often happens that justification never arrives. It's kind of gamble with your source code. Justified abstractions help you reach your goals but unjustified abstractions do the exact opposite:

Every function definition should be justified. The justification isn't that the code is hidden elsewhere. You don't do abstractions to hide code. You do them to make the code simpler and more maintainable. Every call is an indirection which requires the reader to understand what the callee is doing. Every abstraction has a cost.

It is possible that prematurely done abstractions do not always end up unjustified, but that's an exception. Repeated gambles mean that the code gathers unnecessary constructs as time passes. It's the kind of game where you lose big by definition.

To prove that it correct to myself, I tried it few days ago. I wrote a stub for platformer game. I started it by implementing a tilemap that I can edit. I've made this kind of things before, but this time I avoided doing abstractions too early. The following patterns started to emerge:

This advices against studying design patterns. If they're needed, they will emerge without having to figure them out. If they're not, it's a cardinal error to introduce them into your code prematurely.

To get most of abstractions you need to avoid introducing them yourself. You don't need to force. Let the code show the form it wants to take.