(0) If you need to know or care about its implementation details when you use it, it's not an abstraction.
(1) If unrelated ad hoc cases are hardcoded together into a single procedure, it's not an abstraction.
(2) If it needs fifteen tunable parameters, some combinations of which don't even make sense, it's not an abstraction.
At some point in time, programmers discovered that selection (if, switch, pattern mathcing, whatever) could be replaced with dynamically dispatched first-class procedure calls. Since then, they haven't stopped making their code more “abstract” by making their control flow impossible to follow. Alas, this isn't real abstraction, because it doesn't achieve the intended purpose of reducing the number of things you have to keep in your head simultaneously.
So, rather than blaming “wrong abstractions”, I'd blame “not real abstractions”.
Two of the most popular languages out there, C++ and JavaScript, are both great at this.
Sometimes, too great.
(0) The usual symbol for complex number addition is +.
(1) The operation isn't associated to any individual complex number (i.e., it's not an object method), but is rather an intrinsic part of the algebraic structure of the complex numbers.
(2) Complex numbers don't have a physical object identity in memory.
C++ fares a little better than JavaScript, but not a lot better.
C++ templates allow for almost anything. I have seen incredibly strange things done to the language with templates. Since Templates can be used to parse, and execute, entirely different programming languages, it is hard to imagine a level of abuse to which C++ templates are not amenable.
That doesn't mean anything. With enough determination, anything can be turned into “something very unrecognizable”. Heck, sometimes the results are relatively pleasant even: http://libcello.org/ . But, if a language doesn't allow you to define basic abstractions like complex numbers (not to mention slightly more elaborate ones, like queues that are indistinguishable from one another if they contain the same elements in the same order), then that obviously reflects very poorly on its abstraction facilities.
> C++ templates allow for almost anything. I have seen incredibly strange things done to the language with templates.
What you can't do in C++, however, is make your abstractions not leak. Every template library is one template specialization away from being broken. This is unlike languages that enforce their abstractions by more robust means, like parametricity and macro hygiene.
This needs to be given a catchy phrasing and spread all across developer communities!
WTD == Worse Than Duplication?
WAAW == Wrong Abstractions Are Worse?
Duplication is still bad, and correct abstractions are still good.
For instance, one might say: "The way x is implemented works, but it's not quite the right abstraction, here's why". That is way more informative than saying it's simply the wrong abstraction or considering it good enough and ignoring its deficiencies.
I keep having to simplify the code and it’s exhausting.