Live data from Hacker News

Dennis Ritchie on the priorities of && || vs. == etc. (1982)

lysator.liu.se

141–150 of 178 posts

Re: Dennis Ritchie on the priorities of && || vs. == etc. (1982)

#141

Earlier quoted context omitted.

The Ada language requires explicit parentheses in the case of a succession of different logical operators precisely to avoid precedence-related bugs. [0] In the Pony language, any expression where more than one infix operator is used must use parentheses to remove the ambiguity. [1] The Zig language considered following Pony, but didn't. [2] [0] http://archive.adaic.com/standards/83rat/html/ratl-03-06.htm... [1] http…

Ada is such an underrated language. The lack of its adoption is a testament to the old adage that technologies don't thrive or die on their technical merits.

The late arrival of a Free and Open Source compiler certainly didn't help its adoption in Free and Open Source circles.

Re: Dennis Ritchie on the priorities of && || vs. == etc. (1982)

#142
post #137

Please note that, despite the misleading title, TFA is about the precedence of bitwise operators & and | with respect to the comparison operators (== and all the others). In particular it was asked to Ritchie why the former are weaker than the latter in C, a rule generally considered a mistake because it makes it impossible to write common expressions like if (addr & mask == 0) without adding extra parentheses: if ((…

Thank you for this additional context. So in short, bitwise operators have lower precedence than comparisons to allow you to write: if (a==b & c==d) ... but of course, this means you can't write bitwise checks like this: if (addr & mask == 0) ... The problem could theoretically have been solved when the shortcut operators were introduced, by increasing the precedence of & and | to be higher than comparisons, but have…

> you could write [...] but of course, this means you can't write

I found this rather difficult to read. You could write those expressions. They're legal C code. Whether they will have the expected semantics will depend on, well, what you expected.

The more general problem is code that relies too heavily on precedence rules in the first place. Precedence-related bugs and readability issues are easily avoided, just use parentheses. As I mentioned in another comment in this thread, some languages force the programmer to do this.

Re: Dennis Ritchie on the priorities of && || vs. == etc. (1982)

#143

I don't even know the priority between && and ||. If I'm using both, I use parentheses just so it's more explicit. "a && b || c" should flag a linter, IMO, with "(a && b) || c" or "a && (b || c)" being required.

The Ada language requires explicit parentheses in the case of a succession of different logical operators precisely to avoid precedence-related bugs. [0] In the Pony language, any expression where more than one infix operator is used must use parentheses to remove the ambiguity. [1] The Zig language considered following Pony, but didn't. [2] [0] http://archive.adaic.com/standards/83rat/html/ratl-03-06.htm... [1] http…

If I read this right, Zig follows Pony partially. The very basic stuff like addition and multiplication follows the well known precedence rules („chainable“), but eg bitwise operators whose precedence nobody can remember must be put into parentheses.

I find this a good compromise between being explicit and readability (Lisp syndrome).

Re: Dennis Ritchie on the priorities of && || vs. == etc. (1982)

#144
post #128

Earlier quoted context omitted.

IMO the intuition is to not use any intuition at all: there aren't built-in booleans in C, true is a #define for 1 and false is a #define for 0. For C conditionals, 0 = false, nonzero = true. So a+b != 0 a!=0 or b!=0 a*b != 0 a!=0 and b!=0 Of course this intuition also reveals the pitfall behind this correspondence! You'd better make sure those are unsigned ints or #defined booleans, so you're not using general C exp…

Then what is _Bool, if not a built in boolean type?

I genuinely forgot stdbool.h existed, I don't actually write that much C myself.

My point was more around the conditionals being weakly typed around unsigned ints rather than a specific lack of built-ins. A lot of commenters were going into arithmetic mod 2 or philosophical issues, neither of which actually apply here.

Re: Dennis Ritchie on the priorities of && || vs. == etc. (1982)

#145

Earlier quoted context omitted.

I think most people agree "a*x**b + c" is more clear than "(a*(x**b))+c". Or "a+b+c+d" is more clear than "a+(b+(c+d))". Why are we happy to avoid parentheses for these operations but not for && and ||? Probably because we are all really used to the precedences for + and *. So at the end of the day, what's more clear depends on How familiar the engineers working on your code are with a given set of operators.

Just nitpicking: "a+b+c+d" in C is equivalent to "((a+b)+c)+d" not to "a+(b+(c+d))". I otherwise agree with your comment: in most cases, unnecessary parentheses make the code slower to read, just like unnecessary "==true".

just a fun little anecdote.

I wrote a piece of code that said ` if ( boolean_variable == true)`

this was meant to be "if neither false nor null", since the variable was nullable (kotlin), until someone else tried to "fix the beginner mistake" :P

luckily kotlin requires you handle the nullability and the other person immediately figured out what was going on.

The other person was me, a couple of months down the line.

Re: Dennis Ritchie on the priorities of && || vs. == etc. (1982)

#146
post #137

Earlier quoted context omitted.

Thank you for this additional context. So in short, bitwise operators have lower precedence than comparisons to allow you to write: if (a==b & c==d) ... but of course, this means you can't write bitwise checks like this: if (addr & mask == 0) ... The problem could theoretically have been solved when the shortcut operators were introduced, by increasing the precedence of & and | to be higher than comparisons, but have…

> you could write [...] but of course, this means you can't write I found this rather difficult to read. You could write those expressions. They're legal C code. Whether they will have the expected semantics will depend on, well, what you expected. The more general problem is code that relies too heavily on precedence rules in the first place. Precedence-related bugs and readability issues are easily avoided, just us…

Sure, you can use parentheses everywhere, but the code would be quite noisy. Do you think this:

  ((window.location).href) == foo;
is more readable than:

  window.location.href == foo;

Re: Dennis Ritchie on the priorities of && || vs. == etc. (1982)

#147
post #123
post #8

Earlier quoted context omitted.

Convert them to arithmetic. If you ignore the casting, a && b is just a * b a || b is just a + b Now you remember the precedence between them (except in broken languages, of which the only notable one is shell).

> except in broken languages, of which the only notable one is shell The array language people (APL, J, K) are going to come in and protest, but you aren't going to be able to understand them. /s

Hey, even Dijkstra agrees with us on this one:

> I remember how much more pleasant the predicate calculus became to work with after we had decided to give con- and disjunction the same binding power and thus to consider p ∧ q ∨ r an ill-formed formula.

https://www.cs.utexas.edu/users/EWD/ewd13xx/EWD1300.PDF (page 4-5)

Re: Dennis Ritchie on the priorities of && || vs. == etc. (1982)

#148

I don't even know the priority between && and ||. If I'm using both, I use parentheses just so it's more explicit. "a && b || c" should flag a linter, IMO, with "(a && b) || c" or "a && (b || c)" being required.

This is the best way in my opinion. Sacrifice a second of typing for clarity. I try to do this with expressions in general.

Re: Dennis Ritchie on the priorities of && || vs. == etc. (1982)

#149
post #137

Please note that, despite the misleading title, TFA is about the precedence of bitwise operators & and | with respect to the comparison operators (== and all the others). In particular it was asked to Ritchie why the former are weaker than the latter in C, a rule generally considered a mistake because it makes it impossible to write common expressions like if (addr & mask == 0) without adding extra parentheses: if ((…

Thank you for this additional context. So in short, bitwise operators have lower precedence than comparisons to allow you to write: if (a==b & c==d) ... but of course, this means you can't write bitwise checks like this: if (addr & mask == 0) ... The problem could theoretically have been solved when the shortcut operators were introduced, by increasing the precedence of & and | to be higher than comparisons, but have…

Why was it important to allow you to write:

    if (a==b & c==d)
I always thought using the bitwise operator as if it were a logical operator was simply a mistake, even though it works because false is 0 and true is 1.

Edit: Mea culpa for reading and responding to the comments before the article.

Re: Dennis Ritchie on the priorities of && || vs. == etc. (1982)

#150
post #137

Earlier quoted context omitted.

Thank you for this additional context. So in short, bitwise operators have lower precedence than comparisons to allow you to write: if (a==b & c==d) ... but of course, this means you can't write bitwise checks like this: if (addr & mask == 0) ... The problem could theoretically have been solved when the shortcut operators were introduced, by increasing the precedence of & and | to be higher than comparisons, but have…

Why was it important to allow you to write: if (a==b & c==d) I always thought using the bitwise operator as if it were a logical operator was simply a mistake, even though it works because false is 0 and true is 1. Edit: Mea culpa for reading and responding to the comments before the article.

Because before there was && the & was used to mean the same as && does today. This happened when the context was Boolean such as an if.
Post reply on HN