When DRY Argues With KISS and AHA
DRY has a dark side. A blind fight with any repetition often creates heavier code than the repetition itself. A universal function gradually gets new parameters, modes, and exceptions - and what was meant to "remove a duplicate" turns into a tangle everyone is afraid to touch.
Here DRY collides with KISS (the solution is no longer simple) and with AHA (the abstraction was extracted too early). The conflict is resolved not by counting identical fragments but by the question of the reason to change.
The moment to merge is a shared reason, not a second similarity. A good moment to bring code together comes not after the second similar fragment but after a clear shared reason for their change appears. Two functions can be similar and still solve different tasks - then let them stay separate.
The practical takeaway is simple: repetition is a deliberate trade-off, not always a mistake. A bit of duplication for the sake of clarity and independence of parts is often cheaper than a premature generalization. Let's see this in code - in the difference between false and deliberate DRY.