Refer back to the bold portion of Andrey’s text: “there is often no better alternative to be found”. What? We’re programming! We’re providing instructions to a machine, which will be faithfully executed on our behalf, regardless of how tedious and repetitive they may be, and there’s no better alternative than copying and pasting?
To be honest, I thought Andrey’s perspective was one that might be right in C++ but is missing the whole other universe of languages out there. While FP language are not bug free, a few of these particular cases would not show up in most FP code I have worked in, the culture is just to provide higher level abstractions whenever you find yourself repeating things. But to be fair, that is the FP culture I force everyone I work with into not necessarily the community at large. But it is much easier, IMO, to make these abstractions than in C, C++ or Java.
qreal x = ctx->callData->args.toNumber();
qreal y = ctx->callData->args.toNumber();
qreal w = ctx->callData->args.toNumber();
qreal h = ctx->callData->args.toNumber();
if (!qIsFinite(x) || !qIsFinite(y) || !qIsFinite(w) || !qIsFinite(w))
Would much more likely be written as the following if I were doing it in Haskell.
List.any ~f:qIsFinite [x; y; w; h]
if (protocol.EqualsIgnoreCase("http") ||
Would be, something like:
So, yes, the author is right that the options are limited in C++, but that is not because C++ represents the pinnacle of abstractions but because it represents a rather low point in abstractions. I’d love to see what the Rust answer is here. @steveklabnik?
Well, we have AST-based macros, and while they have lots of room for improvement, they should be more like Racket and less like #define.
I would also use iterators and write, like your Haskell:
[x, y, w, h].iter().any(|x| !x.finite())
or, if we could use UFCS, though I’m not sure how it interacts with the !, and it’s Saturday so I’m lazy, so let’s flip it to a negative test:
[x, y, w, h].iter().any(Foo::not_finite)
You could do the same for your last case as well.