Hacker News new | ask | show | jobs
by paulsutter 4883 days ago
I love the Erlang example, I've been curious about Erlang and that's a powerful demonstration of conditional-free programming, contrary to the author's intent.

Sorry, but "n < 2" is a conditional, whether you're using an if statement, the "?" operator, or to reference an array of function pointers (at least from this old-school C/assembler programmer's perspective). Whereas that Erlang code looks elegantly conditional-free. Clearly branching will appear behind the scenes, but the Erlang code has no conditionals.

3 comments

Pedantic: "n>2" is a comparison operator, and doesn't incur a branch. if statements, ternary operators, etc are conditionals. The effect in the article is the same though, without the potential for a mispredict penalty.

Whether that's actually faster is debatable though. If you're writing in C, you're probably concerned about performance, and the function pointer invocation is going to be a lot slower than a branch mispredict. A sufficiently complex array dereference will slow it down too, but I wouldn't be surprised if the compiler can turn simple cases like this into an equivalent switch/jumptable.

Thus conditional-free programming (as presented here, in C) is mostly academic. Debug tracing is an interesting application, but readability and performance both suffer.

If a language could internalize conditional-free constructs natively, however, it could be an interesting study.

`n > 2` could be a comparison operator in some architectures. For example, in dcpu16 (fictional, but I'm sure this was inspired from somewhere), `a = b > 2` would be written as:

    set A, 0
    ifg B, 2
      set A, 1
It conditionally evaluates a machine instruction, which is, indeed, branching.
>> Thus conditional-free programming (as presented here, in C) is mostly academic

Do you think this is true because C code has traditionally relied so heavily on branching?

Put another way, perhaps branch-free programming is has greater speed potential, but the tools we use have been heavily optimized for branch-laden programming. Maybe putting sufficient resources into optimizing code for branch-free programming (and stripping out optimizations for branching) would yield faster execution.

I don't know the answer, just musing. I am curious, though.

Well, the "branch-free" paradigm requires pushing a stack frame and making a jump to the passed function (requiring a pointer lookup) and a jump back to the calling function. In the branching paradigm, only one execution path requires a jump at all, and that jump is made based on an offset embedded directly into the machine code, so the additional pointer lookup is not needed.

So, I'm going to come down on the side of the traditional model being inherently more performant.

agree about the conditional, I was expecting some sort of functional alternative and was interested by the title, but on reading and realizing that the OP is proposing that "(n < 2)" evaluation and calling a func ptr as non-conditional programming is simply not true, that's conditional programming.
I consider "n < 2" to be an expression evaluating to either true (1) or false (0). You can do basic if-else branching by considering true/false statements as conditions to if/elseif/else branching, but true/false cannot be used to evaluate only parts of a function by itself. That's what I intended to express, sorry if it's not evident.
What constitutes a "part of a function" in the article is a little confusing to me, for example: "I consider it as 'cheating' as we now have evaluated only parts of the function." Once you pass functions to a function, are those "part of the function"? If we say no, they're just arguments, it seems to sidestep the issue in an unsatisfying way; I could rewrite all my functions to take all the functions they call as arguments (dependency injection taken to the extreme) and suddenly all my functions have... no parts? That can't be right! On top of that, looking up an entry in a list (even one of functions), given an integer index, in a functional language, is arguably a series of conditional tests (is index 0? is index-1 0? is index-2 0? ...) Overall it's a fair article, but I think there have been a number of esolangs over the years that have tried to turn the idea of the conditional on its head, as well; more references might make it stronger.