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.
Dennis Ritchie on the priorities of && || vs. == etc. (1982)
141–150 of 178 posts
Re: Dennis Ritchie on the priorities of && || vs. == etc. (1982)
#142Please 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…
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)
#143I 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…
I find this a good compromise between being explicit and readability (Lisp syndrome).
Re: Dennis Ritchie on the priorities of && || vs. == etc. (1982)
#144Earlier 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?
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)
#145Earlier 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".
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)
#146Earlier 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…
((window.location).href) == foo;
is more readable than: window.location.href == foo;Re: Dennis Ritchie on the priorities of && || vs. == etc. (1982)
#147Earlier 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
> 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)
#148I 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.
Re: Dennis Ritchie on the priorities of && || vs. == etc. (1982)
#149Please 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…
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)
#150Earlier 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.