You know, programming is hard, so programmers are easily seduced by apparent quick fixes, such as language features which seem to map onto functional requirements.
And programmers are smart, so when those quick fixes turn out to be problematic — when the mapping from language feature to functional requirement proves to be just a hair inside – no problem! we stay up all night and hack around the problems, because that way we can keep our quick fix.
And when it turns out that some of the things we hoped to solve with our quick fix don’t yield to it, Hey, no
problem! We still covered /some/ of the problems with the quick fix we have to stay up all night with again tonight because — surprise,surprise — the quick fix has another issue we are smart enough to hack around.
Sure, we now have to find some Other Way to solve the cases not covered by the Quick Fix, and that approach of course would work for the simple cases the language feature mapped onto, but we won’t use that Other Way for all the cases, because the Quick Fix we will now be maintaining in addition to the Other Way is, uh…well…you know, so, um, quick.
I’ve done my share of the “Quick Fix”. You get so far down the hole of writing the Quick Fix, you don’t want to use the “Other Way” because you’ve spent, nay, invested all that time on the not so quick Quick Fix.