Live data from Hacker News

Is This a Branch?

bartwronski.com

51–60 of 78 posts

Re: Is This a Branch?

#51
post #47
post #42

As usual, the programmer should look at the generated assembly, when reasoning about performance. Sometimes compilers are smart, optimizing away things people wouldn't imagine they can, and sometimes they are really dumb, pessimizing code in unimaginable ways (to the extent that just deleting code from the output, which doesn't naturally correspond to anything in the source code, makes the output better). Relying on…

This sounds tempting, but it would trigger a wave of unreadable, irrelevant micro optimization by many programmers. If you have a desired assembly result, write it yourself in the first place. The one concession to this I would like is a "constant time" marker for cryptography functions where it is an absolutely critical property that there be no data dependant branches. (This is a little different on GPUs where bran…

I've been designing a programming language where nothing is a side-effect – including calling conventions, processor caches, branch predictors, locks, graphics modes, etc.. “Runtime has to be independent of the value of the input” would be how that language expresses "constant time" – and it would take into account every part of the compiler's model of the target architecture (which, by the way, is also described in the code) so for a sufficiently-simple, sufficiently-well-modelled architecture, the generated code could be provably Spectre-proof – given sufficient assumptions (Eis's take on Rust's `unsafe`).

It's very early days, but I hope to get something usable by 2025.

Re: Is This a Branch?

#52
post #31

Earlier quoted context omitted.

We're talking C. As soon as a ternary calls a function, all bets are off what could be happening in addition to the value being computed. And thanks to the preprocessor, any identifier could potentially be calling a function.

Hmm? Which part implies “all bets are off”? There’s the condition (evaluated first), the true case and the false case. Only one of the cases is evaluated. I’m assuming you were alluding to some sort of “ x++ = x++ * *x++” style situation, but the ternary expression isn’t a statement and there are sequence points in between. As a bonus, the first result for “ternary operator evaluation order” gave me someone who linke…

> Hmm? Which part implies “all bets are off”

Remember, the received wisdom of HN programmers is the C is black magic.

Re: Is This a Branch?

#53

Earlier quoted context omitted.

I have been reading HN for a long time but your comment is the first time I violently felt the need to create an account and respond. I want you to consider how significant that is. Ternaries are NEVER easier to read.

Meh. When sufficiently terse, ternary expressions are frequently more readable than a more verbose if/else equivalent. I would agree that ternaries can get out of hand quickly though.

What (besides the words if and else and the curly braces) makes the if/else equivalent more verbose)?

Re: Is This a Branch?

#54
post #33
post #19

Earlier quoted context omitted.

Imho the problem with the ternary isn't the concept but the literal ?: symbols used for it. So many languages use clear words like "if" and "then" and "else" and parens and curly braces for conditional statements... But then they go full Perl and mash their faces against the keyboard when developing syntax for conditional expressions. It's bone-headed language-design that C did wrong and everybody else continues to d…

I've been messing around with some code that uses: #define TERN(c, a, b) c ? a : b I'm not a fan of ternaries, but that macro makes it kind of more ligible.

I don't advocate the use of this macro, but if you do use it you should really wrap the parameters and the whole expression in parentheses to avoid precedence issues:

  #define TERN(c, a, b) ((c) ? (a) : (b))

Re: Is This a Branch?

#55
post #48
post #40

Earlier quoted context omitted.

> where a complex ternary is probably the best choice Under what circumstances would that happen? I've never encountered a nested ternary that wouldn't be better replaced with readable code, so now I'm wondering what experiences I've been missing. :)

Readability is in the eye of the beholder.

Yes, good point. Still, when working on a shared codebase, it's good to take more potential beholders into account. I suppose if there is a common, consistent style that you can expect everyone to be familiar with, you can get used to reading a sensible amount of chained ternaries.

Re: Is This a Branch?

#56
post #47

Earlier quoted context omitted.

This sounds tempting, but it would trigger a wave of unreadable, irrelevant micro optimization by many programmers. If you have a desired assembly result, write it yourself in the first place. The one concession to this I would like is a "constant time" marker for cryptography functions where it is an absolutely critical property that there be no data dependant branches. (This is a little different on GPUs where bran…

I've been designing a programming language where nothing is a side-effect – including calling conventions, processor caches, branch predictors, locks, graphics modes, etc.. “Runtime has to be independent of the value of the input” would be how that language expresses "constant time" – and it would take into account every part of the compiler's model of the target architecture (which, by the way, is also described in…

> processor caches, branch predictors

You can't "take this into account" because it requires state that isn't visible to you and also requires you to know the design of future hardware!

Re: Is This a Branch?

#57
post #40

Earlier quoted context omitted.

When I find a place where a complex ternary is probably the best choice, I'm a big fan of the following format, because I find it clear that each line is a new condition myvar = condition_1 ? value_1 : condition_2 ? value_2 : condition_3 ? value_3 : value_fallback;

> where a complex ternary is probably the best choice Under what circumstances would that happen? I've never encountered a nested ternary that wouldn't be better replaced with readable code, so now I'm wondering what experiences I've been missing. :)

I don't have an example handy, but it's useful in exactly the same cases where you would use a Lisp "cond" construct; testing a bunch of conditions one after the other. Using an "if / else if / ... / else" construct can do the same thing, but it can be less clear sometimes (both to intent and because it takes up more screen real estate, which makes understanding the overall code harder).

Re: Is This a Branch?

#58
post #46
post #42

As usual, the programmer should look at the generated assembly, when reasoning about performance. Sometimes compilers are smart, optimizing away things people wouldn't imagine they can, and sometimes they are really dumb, pessimizing code in unimaginable ways (to the extent that just deleting code from the output, which doesn't naturally correspond to anything in the source code, makes the output better). Relying on…

This is one things I like so much about SBCL, it not only compiles the Lisp code directly to native code, with the disassemble function you can print out the generated code for each function to see how much the compiler was able to optimize a function. This is especially important in the context of dynamic languages to see where generic operators have to be called and where the type inferencer was able to compile it…

Many Lisp compilers do that.

What makes SBCL special is a) using type information as compile-time assertions and b) the level of diagnostic output during compilation. The compiler explains in detail when operations can't be optimized further, for example because of lack of type information.

Re: Is This a Branch?

#59
post #3

Ifs are generally bad for readability though, because they force the reader to understand your control flow. Replacing an if with a ternary makes it more readable, not because the generated code is any different, but because a reader immediately knows that they don't need to scan through the two sides for control flow constructs (because the two sides of the ternary are guaranteed to be expressions rather than blocks…

I have been reading HN for a long time but your comment is the first time I violently felt the need to create an account and respond. I want you to consider how significant that is. Ternaries are NEVER easier to read.

I'd prefer something like

    printf(condition? "YES": "NO");
than something like

    if (condition) {
        printf("YES")
    } else {
        printf("NO")
    }

Re: Is This a Branch?

#60
post #33
post #19

Earlier quoted context omitted.

Imho the problem with the ternary isn't the concept but the literal ?: symbols used for it. So many languages use clear words like "if" and "then" and "else" and parens and curly braces for conditional statements... But then they go full Perl and mash their faces against the keyboard when developing syntax for conditional expressions. It's bone-headed language-design that C did wrong and everybody else continues to d…

I've been messing around with some code that uses: #define TERN(c, a, b) c ? a : b I'm not a fan of ternaries, but that macro makes it kind of more ligible.

That isn't more readable. It's non-standard. It also looks like a function call, but doesn't behave like one (in a function call, a, b, and c would all be evaluated). It's going to confuse other C programmers.

As Liquid_Fire points out, it's also probably incorrect.

Post reply on HN