Live data from Hacker News

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

lysator.liu.se

81–90 of 178 posts

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

#81
post #8

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.

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

All binary messages in Smalltalk (messages with selectors consisting of punctuation, like !@+-, including punctuation sequences like "+-&|", if you want) have the same precedence, and the keyword variants (which short-circuit, using block arguments) and: and or: also have the same precedence (one level lower than the binary/punctuation messages), but because they take block arguments, are usually disambiguated:

    a | (b & c) "parens needed to ensure b & c is evaluated first"
        ifTrue: [self doSomething]
        ifFalse: [
                "because the and: is sent in a block arg to or:, it won't be evaluated unless or:'s receiver is false"
                (self hasPendingTask or: [self updateTaskQueue and: [self hasPendingTask]])
                        ifTrue: [self processTask]]
Smalltalk is extremely elegant, powerful, and simple. 6 reserved words, 3 levels of operator precedence, and not much syntax to learn. It's what r5rs Scheme should have been.

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

#82
post #17
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).

1+1=1? My maths education was a long time ago, but I triple checked with my calculator, and I'm uncertain this is quite right. My own mnemonic: SAXO. Shift, And, Xor, Or. (Like a real Saxo, it's fun to go a bit faster like this, but you do have to trust everybody involved, because any accident is probably going to end up badly for you.) And now you know the bitwise precedence as well! And this ordering actually works…

I suspect that most people here won’t get the joke. Renault pulled out of the US market 40 years ago, and was never more than a tiny player.

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

#83
post #40

Unfortunately even though this was called out as a mistake in 1982, much more modern languages (e.g. C#) are still copying it. As painful as breaking changes might be, they beat the alternative of dealing with a bad design indefinitely. At least in more modern languages, the type checker usually catches the mistakes caused by this design mistake.

> much more modern languages (e.g. C#) are still copying it

Fortunately Go, Rust, and Swift all chose to defy C and fix the precedence of &, which I expect sets enough of a precedence (heh) for every language for the rest of human history to get it right.

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

#84

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.

Smalltalk doesn't have operator precedence rules. They just apply left-to-right. The infix operators aren't part of the language - they're messages (aka methods), and precedence would be inconsistent with the language's simple syntax.

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

#85
post #6

Earlier quoted context omitted.

Consider (&& a b) and (|| a b) for no uncertainty over operator precedence and easy variadic representation (&& a b c) at the cost of zero additional parentheses.

While true and might be easy to read in the example context of a b c I'd imagine having the && separator in real world conditions to be far more readable and clear for vast majority if people

Pipe looks far too much like a 1 or lowercase ell.

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

#86
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).

Isn't it x ^ y which is like x + y?

^ is like + when operating over bits, since (bit)2 == 0

| is like + when operating over bools, since (bool)2 == 1

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

#87
post #38

Earlier quoted context omitted.

There is: The neutral element for + is 0 ( x + 0 = x for any x ). The neutral element for * is 1 ( x * 1 = x for any x ). Furthermore, you have arithmetic properties like x * 0 = 0 for any x (annulation) or ( x + y ) * z = ( x * z ) + ( y * z ) for any x , y , z (distributivity). Similarly: The neutral element for OR is false ( x OR false = x for any x ). The neutral element for AND is true ( x AND true = x for any x…

I've never heard of saturation arithmetic and now it all makes sense. Otherwise I thought it was more common to think of XOR as boolean addition, and OR would be represented as xy + x + y.

Saturation is actually the wrong way to think about bools when other operations get involved:

saturate(0 - 1) = 0

bool(0 - 1) = 1

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

#88
post #4

Somewhere, I sat down and wrote a combined precedence table across many languages. It was quite hairy; sometimes there's even variation across language versions. Besides `not` (which often has different precedence depending on whether it's a keyword or a punctuator, and is a great reminder that multiple levels of pratt parsing is meaningful), `await` is the one with the most variation - in most languages, it binds ti…

> `await` is the one with the most variation [..] in C++ it's just barely tighter than assignment. That doesn't seem right to me. According to cppreference[1] it's the operator with the third-highest precedence, well above assignment, which is the second-lowest. [1] https://en.cppreference.com/w/cpp/language/operator_preceden...

Hm, I looked at Wikipedia, and I'm pretty sure cppreference used to agree with it? Did it ever differ between drafts?

I've gotten surprisingly out of touch with the C++ world, even though it was my first serious language and I used to have the draft numbers memorized ...

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

#89

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.

I'm always surprised when people don't know this one because they're like multiplication and clamped addition.

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

#90

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.

Consider (&& a b) and (|| a b) for no uncertainty over operator precedence and easy variadic representation (&& a b c) at the cost of zero additional parentheses.

... at the cost of having parentheses around every subexpression.
Post reply on HN