Live data from Hacker News

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

lysator.liu.se

31–40 of 178 posts

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

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

Is there an intuition for this correspondence otherwise I don't think it's very helpful

Kudos to the people that responded to explain why the correspondence is helpful.

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

#32
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…

> 1+1=1?

True + True = True, because "true" means "not zero" and "false" means "zero". In most all languages that permit int->bool casting, if(2) will evaluate to "true".

The warnings clang and FCC generate are a style warning because it's unclear on casual reading. Even readers who know the precedence rules will typically want to insert the parentheses manually. If the meaning were undefined, the compiler would give an error, not a warning.

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

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

0x8000 && 2 != 0x8000 * 2

-1 || 1 != -1 + 1

0x8000 || 0x8000 != 0x8000 + 0x8000

(with a 16-bit integer, adjust accordingly for larger word sizes)

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

#35

There's a niche language called Sail that has & and | act as both bitwise and boolean operators. It actually works really well and isn't confusing at all after the initial "this is different". There's no real downside because it is a modern strictly typed language unlike C. On the other hand I don't know if there's a real upside either. It's not very difficult to use && and || and it serves as extra documentation, an…

Most langages with a passing link to C support & and | on booleans (even when they have a legitimate non-integer boolean type). However they are eager which makes them generally useless.

^ is a lot more valuable.

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

#36

There's a niche language called Sail that has & and | act as both bitwise and boolean operators. It actually works really well and isn't confusing at all after the initial "this is different". There's no real downside because it is a modern strictly typed language unlike C. On the other hand I don't know if there's a real upside either. It's not very difficult to use && and || and it serves as extra documentation, an…

Pascal also uses the same operators for bitwise and logical and and or and they’re simply and and or.

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

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

Is there an intuition for this correspondence otherwise I don't think it's very helpful

I always remember it in terms of set operations. && corresponds to set intersection, while || corresponds to set union. The union operation is similar to "adding" two sets together. You also have the distributive property: a && (b || c) == (a && b) || (a && c).

The analogy isn't perfect, because || is also distributive over &&, but addition isn't distributive over multiplication. I think this is actually one of the essential properties that distinguishes a Boolean algebra from a ring. Someone with more knowledge of abstract algebra could probably provide more insight here, though.

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

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

Is there an intuition for this correspondence otherwise I don't think it's very helpful

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

Furthermore, x AND false = false for any x, and (x OR y) AND z = (x AND z) OR (y AND z) for any x, y, z.

So OR works very much like + algebraically, and AND works very much like *.

When using 0 and 1 for false and true, AND is exactly the same as multiplication, and OR is like addition with saturation arithmetics (i.e. 1 + 1 = 1).

The common precedence rules stem from those parallels.

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

#39

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.

Sorry, but I'm of the exact opposite opinion. If you don't know, learn. It's not hard (as other sibling comments have noted). Code with superfluous parentheses is even more confusing, since I expect them to be present only when overriding precedence.

...and I just realised your username adds some additional irony.

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

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

Post reply on HN