1. 5

  2. 2

    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?

    Yes please!

    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.

    For example:

    qreal x = ctx->callData->args[0].toNumber();
    qreal y = ctx->callData->args[1].toNumber();
    qreal w = ctx->callData->args[2].toNumber();
    qreal h = ctx->callData->args[3].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") ||
    protocol.EqualsIgnoreCase("https") ||
    protocol.EqualsIgnoreCase("news") ||
    protocol.EqualsIgnoreCase("ftp") ||
    protocol.EqualsIgnoreCase("file") ||
    protocol.EqualsIgnoreCase("javascript") ||
    protocol.EqualsIgnoreCase("ftp")) {

    Would be, something like:

    List.any ~f:(equalsIgnoreCase protocol) ["http"; "https"; "news"; "ftp"; "file"; "javascript"]

    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?

    1. 2

      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.