News for hackers. Stuff that matters.
Re:Dennis Ritchie on the priorities of && || vs. == etc. (1982) by Sohcahtoa82 on Friday January 05, 2024 @05:26PM (#38885868)
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.
Re:Dennis Ritchie on the priorities of && || vs. == etc. (1982) by o11c on Friday January 05, 2024 @05:36PM (#38885977)
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).
Re:Dennis Ritchie on the priorities of && || vs. == etc. (1982) by anonnon on Friday January 05, 2024 @07:32PM (#38886986)
> 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) by neilv on Saturday January 06, 2024 @12:53AM (#38888826)
> Smalltalk [...] what r5rs Scheme should have been.

I'm a fan of both languages, but R5RS Scheme was to be an algorithmic language, and Smalltalk is a particular flavor of OO language (class-instance, single dispatch).

Would you say that doing conditionals and Boolean expressions with Smalltalk's object semantics and `ifTrue:ifFalse:` and mix of `and:` and `&` etc. is cleaner than Scheme's `if`, `and`, etc. syntax?

> 3 levels of operator precedence,

Scheme doesn't see what's wrong with fewer:

    (if (or a (and b c))
        (do-something)
        (if (or (has-pending-task)
                (and (update-task-queue)
                     (has-pending-task)))
            (process-task)))
Re:Dennis Ritchie on the priorities of && || vs. == etc. (1982) by anonnon on Saturday January 06, 2024 @01:34AM (#38889029)
By "should have been" I meant striking the balance of simplicity, power, and ease of learning that Smalltalk does. R5RS is simple and powerful (even more powerful due to macros), but not really usable, since it doesn't ship with something like Smalltalk's object model out-of-the box that streamlines creating ADTs and code reuse. Instead they give you the rudiments (functions, closures) and leave everything else up to you.
Re:Dennis Ritchie on the priorities of && || vs. == etc. (1982) by neilv on Sunday January 07, 2024 @05:48PM (#38906034)
Yeah, the lack of a basic record/struct/object was felt quickly in R5RS. (Sure, you can whip up something atop vectors, or alists or other pair structures, or some arrangement of closures.)

SRFI-9 soon introduced a record type, and various Scheme implementations introduced much more.

Racket (nee MzScheme, or PLT Scheme) was one of them that introduced an object system, which was neat in some ways (e.g., mixins), but rougher in others, and thankfully it was limited to pedagogic and GUI use. There was also at least one CLOS-like. Later, Racket got a `struct` concept with some interesting hooks (e.g., inheritance/subtyping), and some simpler version of that might've been a good candidate for R5RS.

I'm don't know where RnRS is going recently, but I could imagine a fundamantal record/struct type, or interfaces more like the current Rust thinking.

Re:Dennis Ritchie on the priorities of && || vs. == etc. (1982) by wirrbel on Saturday January 06, 2024 @04:40AM (#38889978)
Some interesting parallels between the original Scheme and message-passing from "The First Report on Scheme Revisited" by Sussman and Steele

> We were very pleased with this toy actor implementation and named it “Schemer” because we thought it might become another AI language in the tradition of Planner and Conniver. However, the ITS operating system had a 6-character limitation on file names and so the name was truncated to simply SCHEME and that name stuck. (Yes, the names “Planner” and “Conniver” also have more than six characters. Under ITS, their names were abbreviated to PLNR and CNVR. We can no longer remember why we chose SCHEME rather than SCHMR—maybe it just looked nicer.)

> then came a crucial discovery. Once we got the interpreter working correctly and had played with it for a while, writing small actors programs, we were astonished to discover that the program fragments in apply that implemented function application and actor invocation were identical! Further inspection of other parts of the interpreter, such as the code for creating functions and actors, confirmed this insight: the fact that functions were intended to return values and actors were not made no difference anywhere in their implementation. The difference lay purely in the primitives used in their bodies. If the underlying primitives all returned values, then the user could (and must) write functions that return values; if all primitives expected continuations, then the user could (and must) write actors. Our interpreter provided both kinds of primitives, so it was possible to mix the two styles, which was our original objective.

> But the lambda and alpha mechanisms were themselves absolutely identical. We concluded that actors and closures were effectively the same concept.

Re:Dennis Ritchie on the priorities of && || vs. == etc. (1982) by dataflow on Friday January 05, 2024 @05:44PM (#38886065)
Also if you forget which is multiplication and which is addition, remember false is 0 and true is 1, then work it out from there: a * b is only nonzero if both of them are nonzero, so it's AND.
Re:Dennis Ritchie on the priorities of && || vs. == etc. (1982) by threatofrain on Friday January 05, 2024 @05:56PM (#38886194)
Isn't it x ^ y which is like x + y?
Re:Dennis Ritchie on the priorities of && || vs. == etc. (1982) by pcwalton on Friday January 05, 2024 @06:06PM (#38886286)
Yeah, | is technically x + y + x*y over GF(2) (this is the Boolean ring to Boolean algebra relation [1]). The GP is still a good way to remember the precedence though.

[1]: https://en.wikipedia.org/wiki/Boolean_ring#Relation_to_Boole...

Re:Dennis Ritchie on the priorities of && || vs. == etc. (1982) by o11c on Friday January 05, 2024 @07:45PM (#38887071)
^ 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) by pvtmert on Friday January 05, 2024 @07:11PM (#38886841)
xor is more like a substraction...
Re:Dennis Ritchie on the priorities of && || vs. == etc. (1982) by trealira on Saturday January 06, 2024 @03:35AM (#38889677)
Yeah. To sum two bits x and y, the immediate sum is x XOR y, and the carry is x AND y. That's how a simple half-adder circuit can be made.
Re:Dennis Ritchie on the priorities of && || vs. == etc. (1982) by dananabread on Friday January 05, 2024 @05:44PM (#38886064)
Is there an intuition for this correspondence otherwise I don't think it's very helpful
Re:Dennis Ritchie on the priorities of && || vs. == etc. (1982) by layer8 on Friday January 05, 2024 @06:15PM (#38886368)
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) by threatofrain on Friday January 05, 2024 @06:19PM (#38886412)
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.
Re:Dennis Ritchie on the priorities of && || vs. == etc. (1982) by layer8 on Friday January 05, 2024 @06:32PM (#38886549)
Yes, true and false with AND and XOR form a mathematical ring [0]. Still, OR is also an additive operation. IMO one could give OR and XOR the same precedence.

On the other hand, there is no strict need to have a dedicated boolean XOR operator, as it works the same as = (equals).

[0] https://en.wikipedia.org/wiki/Ring_(mathematics)

Re:Dennis Ritchie on the priorities of && || vs. == etc. (1982) by orlp on Saturday January 06, 2024 @06:30AM (#38890539)
More than just a ring, it is the simplest finite field.
Re:Dennis Ritchie on the priorities of && || vs. == etc. (1982) by o11c on Friday January 05, 2024 @07:47PM (#38887089)
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) by dataflow on Friday January 05, 2024 @10:53PM (#38888230)
Fun (but not particularly useful fact) is you can also represent x OR y as 1 - (1 - x)(1 - y). This shouldn't be too weird since x OR y is equal to NOT ((NOT x) AND (NOT y)).
Re:Dennis Ritchie on the priorities of && || vs. == etc. (1982) by nostrademons on Friday January 05, 2024 @06:21PM (#38886439)
There's also a connection to probability: if you want the probability of A and B and C happening and they're independent, it's P(A) * P(B) * P(C). If you want the probability of A or B or C happening and they're mutually exclusive, it's P(A) + P(B) + P(C).

Similar analogue for set theory, as another commenter pointed out.

Re:Dennis Ritchie on the priorities of && || vs. == etc. (1982) by aragonite on Friday January 05, 2024 @05:50PM (#38886137)
Conjunction used to be called logical product, and disjunction logical sum, for the reason the other commenters pointed out.
Re:Dennis Ritchie on the priorities of && || vs. == etc. (1982) by nicklecompte on Friday January 05, 2024 @06:03PM (#38886272)
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 expressions. 1 || -1 is true but 1 + (-1) is false.

Edit: forgot to mention: INT_MAX || 1 is true, but what about INT_MAX + 1 :)

Re:Dennis Ritchie on the priorities of && || vs. == etc. (1982) by vzaliva on Friday January 05, 2024 @06:20PM (#38886431)
"true is a #define for 1" is bad idea. Because when `x` is, say, `2` then `if x` is not the same as `if x==true`.
Re:Dennis Ritchie on the priorities of && || vs. == etc. (1982) by BenjiWiebe on Friday January 05, 2024 @07:08PM (#38886824)
That's just the way C is. If you want to check "truthiness" (as much as you can in C), just do 'if x'.
Re:Dennis Ritchie on the priorities of && || vs. == etc. (1982) by trealira on Saturday January 06, 2024 @03:18AM (#38889579)
Something nice in C is that "if (x)" is always equivalent to "if (x != 0)". NULL is a macro for 0, and so is false. Boolean expressions evaluate to 0 if they don't hold. This isn't true in C++, though.
Re:Dennis Ritchie on the priorities of && || vs. == etc. (1982) by ahoka on Saturday January 06, 2024 @04:45AM (#38890007)
Then what is _Bool, if not a built in boolean type?
Re:Dennis Ritchie on the priorities of && || vs. == etc. (1982) by nicklecompte on Saturday January 06, 2024 @07:17AM (#38890829)
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) by kevin_thibedeau on Saturday January 06, 2024 @09:14AM (#38891590)
_Bool isn't part of stdbool. It's a language keyword. C23 introduces full support for bool with true and false as keywords.
Re:Dennis Ritchie on the priorities of && || vs. == etc. (1982) by dataflow on Friday January 05, 2024 @05:45PM (#38886076)
a * b * c is only nonzero if all of a, b, c are nonzero. That's AND, and should be pretty intuitive.

a + b + c is nonzero if any of them are nonzero. (Remember each value is either 0 or 1.) So that's the intuition for OR.

Re:Dennis Ritchie on the priorities of && || vs. == etc. (1982) by explaininjs on Friday January 05, 2024 @05:50PM (#38886124)
a+b+c is nonzero if any of a or b or c are nonzero.
Re:Dennis Ritchie on the priorities of && || vs. == etc. (1982) by dataflow on Friday January 05, 2024 @05:51PM (#38886145)
Yeah I just added that. I was hesitant initially cause you have to also note they're nonnegative, and that you're treating them like real numbers rather than mod 2.
Re:Dennis Ritchie on the priorities of && || vs. == etc. (1982) by explaininjs on Friday January 05, 2024 @11:54PM (#38888550)
Natural numbers are the natural numbers for me! (ISO 80000-2, of course)
Re:Dennis Ritchie on the priorities of && || vs. == etc. (1982) by fasterik on Friday January 05, 2024 @06:15PM (#38886367)
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) by artsi0m on Friday January 05, 2024 @06:18PM (#38886402)
Yes, sometimes logical AND called logical multiplication and logical OR called logical summation.

It seems clear for me, because I remember learning De Morgan's Laws in electronics class and from one specific level of Turing Complete game.

Re:Dennis Ritchie on the priorities of && || vs. == etc. (1982) by naitgacem on Friday January 05, 2024 @05:47PM (#38886097)
this is the notation used in the chapters about boolean algebra in my digital design course. I think it's pretty neat. I honestly never looked into operator precedence in any language enough to notice the relation.
Re:Dennis Ritchie on the priorities of && || vs. == etc. (1982) by rantingdemon on Friday January 05, 2024 @06:06PM (#38886289)
Kudos to the people that responded to explain why the correspondence is helpful.
Re:Dennis Ritchie on the priorities of && || vs. == etc. (1982) by ksherlock on Friday January 05, 2024 @06:07PM (#38886295)
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) by tom_ on Friday January 05, 2024 @05:50PM (#38886129)
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 out tidily for common operations: "x=a<<sa|b<<sb|c<<sb"; "x=p>>n&m"; "x=x&~ma|a<<sa"; and so on. You do need brackets sometimes, but fewer than you'd think, and it helps the unusual cases stand out.

(Main annoying thing: a lot of compilers, even popular ones such as clang and gcc, don't actually seem to know what the precedence rules actually are, and generate warnings asking you to clarify. Presumably the authors didn't realise that C has an ISO standard, that can be consulted to answer this question? Very surprising.)

Re:Dennis Ritchie on the priorities of && || vs. == etc. (1982) by pcwalton on Friday January 05, 2024 @05:54PM (#38886171)
> (Main annoying thing: a lot of compilers, even popular ones such as clang and gcc, don't actually seem to know what the precedence rules actually are, and generate warnings asking you to clarify. Presumably the authors didn't realise that C has an ISO standard, that can be consulted to answer this question? Very surprising.)

The compilers do know what the precedence rules are, but they know that programmers don't routinely consult the ISO standard, so they emit those warnings to reduce the chance of error. Compilers are tools that are designed to help programmers avoid bugs. If they don't help programmers, they aren't doing their job.

Re:Dennis Ritchie on the priorities of && || vs. == etc. (1982) by userbinator on Friday January 05, 2024 @11:27PM (#38888418)
Alternatively, they're encouraging programmers to be stupid and ignorant, causing a dumbing-down feedback loop which is ultimately damaging in the long term.

It ain't no surprise if you see the crap that passes for software these days and the nosedive in quality, but that's a rant for some other time...

Re:Dennis Ritchie on the priorities of && || vs. == etc. (1982) by LeifCarrotson on Friday January 05, 2024 @06:07PM (#38886293)
> 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) by hinkley on Friday January 05, 2024 @06:49PM (#38886684)
It’s true as long as you don’t chain more than a couple billion Boolean checks.

More importantly, only if you don’t rely on short circuiting logic.

Re:Dennis Ritchie on the priorities of && || vs. == etc. (1982) by TylerE on Friday January 05, 2024 @07:35PM (#38886999)
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) by tom_ on Friday January 05, 2024 @08:46PM (#38887499)
Better than that: the Saxo was from Citroen, who apparently haven't served North America since 1974 ;) The Renault equivalent would probably be the Clio.

(Not a big hot hatch connoisseur though, I must admit - I just remember the Saxo in particular as having a reputation of hitting a bad spot on the tradeoff graph for flimsiness/power/good sense of average member of target demographic.)

Re:Dennis Ritchie on the priorities of && || vs. == etc. (1982) by jovial_cavalier on Friday January 05, 2024 @05:59PM (#38886231)
The analogy between logical AND and multiplication, and logical OR and addition is called Boolean Algebra, and it's very well known.

The analogy is that when you set 1 to true and 0 to false, 1 becomes the identity for AND, and 0 becomes the identity for OR. Just as 1 is the identity for multiplication and 0 is the identity for addition.

X * 0 = 0 | X ^ F = F

X * 1 = X | X ^ T = X

X + 0 = X | X V F = X

X + 1 = ? | X V T = T <-- This one breaks the analogy

With this, you can turn any logical expression into something that looks and feels like normal algebra, with the only weird exception being that both operators distribute over each other:

A * (B + C) = A*B + A*C

A + (B * C) = (A + B) * (A + C)

Re:Dennis Ritchie on the priorities of && || vs. == etc. (1982) by LordShredda on Friday January 05, 2024 @06:00PM (#38886239)
1+1 isn't zero, so it's one.
Re:Dennis Ritchie on the priorities of && || vs. == etc. (1982) by dietrichepp on Saturday January 06, 2024 @02:04AM (#38889173)
My problem here is that I distinguish between multiplication and addition by seeing which one distributes over the other.

  a * (x + y) = (a * x) + (a * y)
However, the reverse doesn’t work…

  a + (x * y) =? (a + x) * (a + y)
Why is this a problem?

  a ∧ (x ∨ y) = (a ∧ x) ∨ (a ∧ y)
  a ∨ (x ∧ y) = (a ∨ x) ∧ (a ∨ y)
Both are true. So, who are we to say that one corresponds to multiplication, and the other corresponds to addition? The two operations are too similar to each other.
Re:Dennis Ritchie on the priorities of && || vs. == etc. (1982) by throwaway421967 on Saturday January 06, 2024 @02:50AM (#38889412)
because 1 \and 0 = 0 same as 1 * 0 = 0 and 1 \or 0 = 1 same as 1 + 0 = 1
Re:Dennis Ritchie on the priorities of && || vs. == etc. (1982) by dietrichepp on Saturday January 06, 2024 @02:55AM (#38889438)
Choosing false = 0 and true = 1 is putting the cart before the horse.

It is equally true that 1*0=0 is the same as false|true=true, and 0+1=1 is the same as true&false=false.

But it is also not true that 1+1=1, so it is probably wrong to equate 'or' with '+'. The operation has the wrong properties.

As someone who sometimes dabbles in electronics, 0 = true makes a lot of intuitive sense to me. You have your pin with an open collector, your pull-up resistor, and “true” (as in, it is true that the transistor is conducting) pulls the voltage to ground, which is 0.

As someone who uses a Unix shell, 0 = true makes a lot of intuitive sense to me.

  $ true; echo $?
  0
  $ false; echo $?
  1
Re:Dennis Ritchie on the priorities of && || vs. == etc. (1982) by ninthcat on Saturday January 06, 2024 @03:42AM (#38889710)
You can interpret 0 and 1 as probabilities. 1 + 1 = 1 in this case makes sense because P(A or B) = P(A) + P(B) - P(A and B). You can interpret "A or B" as a set union and "A and B" as a set intersection. Of course it's easy to draw a three-way correspondence between Boolean arithmetic, the events represented by the empty set and the whole space, and sets within some universe because all the objects are so simple, but these correspondences also generalize well to systems with more than two possible values. The ease of generalizing makes me think it's not just a matter of coincidence or convention that we have 0 <=> false.
Re:Dennis Ritchie on the priorities of && || vs. == etc. (1982) by nyssos on Saturday January 06, 2024 @09:20AM (#38891631)
You've just moved the point where we make the arbitrary choice to here:

> You can interpret "A or B" as a set union and "A and B" as a set intersection.

{True, False, Or, And} and {False, True, And, Or} are two different naming conventions for the exact same structure: the unique boolean algebra on two elements.

Re:Dennis Ritchie on the priorities of && || vs. == etc. (1982) by ninthcat on Saturday January 06, 2024 @01:30PM (#38893846)
A union B is defined as the set of things that are in A or in B; A intersect B is defined as the set of things that are in A and in B. So I don't really see it as an arbitrary choice.
Re:Dennis Ritchie on the priorities of && || vs. == etc. (1982) by carlob on Saturday January 06, 2024 @05:23AM (#38890203)
Actually if you think about Boolean logic as mod 2 arithmetics xor is addition, rather than or.
Re:Dennis Ritchie on the priorities of && || vs. == etc. (1982) by msla on Saturday January 06, 2024 @03:42AM (#38889713)
> 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

Re:Dennis Ritchie on the priorities of && || vs. == etc. (1982) by mlochbaum on Saturday January 06, 2024 @08:00AM (#38891074)
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) by hnlmorg on Saturday January 06, 2024 @05:37AM (#38890262)
Depends on the shell. Murex, for example, follows order of precedence correctly
Re:Dennis Ritchie on the priorities of && || vs. == etc. (1982) by CamperBob2 on Saturday January 06, 2024 @12:13PM (#38893138)
No. Then I have to think about it.

I have (gently) jumped on peoples' cases for not using parentheses in expressions involving these operators, and will continue to do so, thanks.

Re:Dennis Ritchie on the priorities of && || vs. == etc. (1982) by MaxBarraclough on Friday January 05, 2024 @06:40PM (#38886613)
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] https://tutorial.ponylang.io/expressions/ops#precedence

[2] https://github.com/ziglang/zig/issues/114

Re:Dennis Ritchie on the priorities of && || vs. == etc. (1982) by pi-e-sigma on Friday January 05, 2024 @06:43PM (#38886643)
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.
Re:Dennis Ritchie on the priorities of && || vs. == etc. (1982) by MaxBarraclough on Saturday January 06, 2024 @06:46AM (#38890640)
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) by wruza on Saturday January 06, 2024 @10:42AM (#38892309)
I remember reading a discussion on it in a year around <= 2000 and it was a general consensus that Ada’s printed standard is too heavy to move around, let alone implement. Military/corporate-ish affinity didn’t help either.
Re:Dennis Ritchie on the priorities of && || vs. == etc. (1982) by MaxBarraclough on Saturday January 06, 2024 @12:18PM (#38893201)
I see pi-e-sigma beat me to it, but:

C++ is at least as complicated as Ada, both in terms of using the language and in terms of writing a compiler for it.

C++ also sees plenty of use in military applications. The F-35's 141 page C++ coding standard is publicly available, for instance.

https://www.stroustrup.com/JSF-AV-rules.pdf

Re:Dennis Ritchie on the priorities of && || vs. == etc. (1982) by pi-e-sigma on Saturday January 06, 2024 @12:07PM (#38893077)
Compare C++ and Ada. C++ standard is an order of magnitude bigger and more complex and yet C++ is thriving. So Ada's failure definitively is not due to the language complexity. C++ has been supported heavily by the corporate, too. Biggest C++ champion was Microsoft, after all.
Re:Dennis Ritchie on the priorities of && || vs. == etc. (1982) by amelius on Friday January 05, 2024 @07:24PM (#38886931)
What about using the same associative operator multiple times?
Re:Dennis Ritchie on the priorities of && || vs. == etc. (1982) by MaxBarraclough on Saturday January 06, 2024 @06:43AM (#38890627)
Re:Dennis Ritchie on the priorities of && || vs. == etc. (1982) by MrBuddyCasino on Saturday January 06, 2024 @07:04AM (#38890760)
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) by dehrmann on Friday January 05, 2024 @08:18PM (#38887297)
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) by asimeqi on Friday January 05, 2024 @07:09PM (#38886832)
I once implemented a logical expression evaluator to be used as filters on a search page. My boss tested it and filed a bug because he expected OR to have higher precedence than AND. I pointed him to a page with the rules and told him that he could use parenthesis if he wanted to modify the order of precedence. He was sort of convinced but never closed the ticket. Every release he would move it to the next release.
Re:Dennis Ritchie on the priorities of && || vs. == etc. (1982) by JonChesterfield on Friday January 05, 2024 @05:30PM (#38885909)
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.
Re:Dennis Ritchie on the priorities of && || vs. == etc. (1982) by namrog84 on Friday January 05, 2024 @05:34PM (#38885948)
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
Re:Dennis Ritchie on the priorities of && || vs. == etc. (1982) by TylerE on Friday January 05, 2024 @07:37PM (#38887018)
Pipe looks far too much like a 1 or lowercase ell.
Re:Dennis Ritchie on the priorities of && || vs. == etc. (1982) by trealira on Saturday January 06, 2024 @04:13AM (#38889841)
I actually think the variadic logical and is more readable, and wish more languages had it. As long as all the arguments are lined up vertically, you can think of it as a sequence of tests for true that exits at the first failure. It's more obvious with the variadic operator. Contrived comparison:

  if (a != null && x != 0 && a.use_it(x))
  {
      ...
  }


  (if (and (not (null a))
           (/= 0 x)
           (use-it a x))
      ...)
Re:Dennis Ritchie on the priorities of && || vs. == etc. (1982) by NegativeLatency on Friday January 05, 2024 @05:35PM (#38885971)
Most, and possibly all languages I've used day to day do not have prefix operators like that.
Re:Dennis Ritchie on the priorities of && || vs. == etc. (1982) by ant6n on Friday January 05, 2024 @06:04PM (#38886274)
Prefix operators considered harmful for readability.
Re:Dennis Ritchie on the priorities of && || vs. == etc. (1982) by tasty_freeze on Friday January 05, 2024 @08:37PM (#38887433)
... at the cost of having parentheses around every subexpression.
Re:Dennis Ritchie on the priorities of && || vs. == etc. (1982) by torstenvl on Friday January 05, 2024 @11:27PM (#38888420)
I hate Excel for this very reason.
Re:Dennis Ritchie on the priorities of && || vs. == etc. (1982) by moritzwarhier on Friday January 05, 2024 @07:06PM (#38886808)
It bothered me a while for "short" boolean expressions to have a linter expect parens, where I'd simultaneously expect everyone with a high school degree to understand the implicit operator precedence.

Then, since my first bug having been merged that was caused by a && vs || operator precedence mistake, I like my parens-always ESLint rule (or whatever exactly it was called).

Even redundant parens can start to look as pleasent as indents, after getting used to them.

In short, I think expressions like (a && b || c && d || e) are a footgun and linters should forbid them. Parens fit well with logical thinking, similar to relative clauses in language.

Re:Dennis Ritchie on the priorities of && || vs. == etc. (1982) by nealabq on Friday January 05, 2024 @07:36PM (#38887008)
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) by JohnFen on Friday January 05, 2024 @06:53PM (#38886711)
I know the priorities of these, but I still use parentheses to make the precedence explicit. I think it's just great practice -- and it makes things easier for the next dev who might have to work with the code.
Re:Dennis Ritchie on the priorities of && || vs. == etc. (1982) by userbinator on Friday January 05, 2024 @06:15PM (#38886378)
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) by sublinear on Friday January 05, 2024 @06:31PM (#38886534)
Explicit is better than implicit. I think the real problem is not breaking up complicated expressions. If it's more than just a few pairs of parentheses making it hard to read there's something more wrong there.
Re:Dennis Ritchie on the priorities of && || vs. == etc. (1982) by thomasahle on Friday January 05, 2024 @07:09PM (#38886833)
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.

Re:Dennis Ritchie on the priorities of && || vs. == etc. (1982) by djur on Friday January 05, 2024 @11:22PM (#38888393)
Most people might agree with that, I don't know, but I know I don't think your first example is clearer. And I've had the operator precedence rules memorized for decades. Parentheses save my brain a step.

The second example is irrelevant because addition is commutative so the parentheses are meaningless. (This is why languages shouldn't override + to be a concatenation operator.)

Re:Dennis Ritchie on the priorities of && || vs. == etc. (1982) by tsimionescu on Saturday January 06, 2024 @02:48AM (#38889403)
The important part that makes the parens in the second operation unnecessary is that addition is associative, not that it's commutative. And concatentation is also associative, so even if those were strings, the parens would still be unnecessary.

That is, (a+b)+c == a+(b+c).

Interestingly, C integer addition is not actually associative, since (1+INT_MAX) + (-1) is UB, but 1+(INT_MAX+(-1)) should in principle be defined as INT_MAX.

Re:Dennis Ritchie on the priorities of && || vs. == etc. (1982) by xigoi on Saturday January 06, 2024 @03:43PM (#38895251)
And floating-point addition is not associative in any language:
Re:Dennis Ritchie on the priorities of && || vs. == etc. (1982) by akira2501 on Saturday January 06, 2024 @12:21AM (#38888673)

    ((x**b) * a) + c
Is equivalent and is the clearer way to express it.
Re:Dennis Ritchie on the priorities of && || vs. == etc. (1982) by saberience on Saturday January 06, 2024 @01:11AM (#38888926)
I think the opposite, I think most people would prefer the version with parentheses, including myself, also, in 20 years experience all companies I’ve worked for would prefer the second expression.

The first expression looks messy and confusing, the second is completely clear in how it will work.

Re:Dennis Ritchie on the priorities of && || vs. == etc. (1982) by userbinator on Saturday January 06, 2024 @01:57AM (#38889133)
Parentheses need to be matched. That adds cognitive overhead. It's especially frustrating when you find the closing parenthesis and then realise it wasn't even necessary.

IMHO it's on a similar level as "== true" "== false" and variations thereof --- absolutely redundant and unnecessary, and shows a lack of knowledge. The same "explicit is better than implicit" mantra is often repeated to justify the latter, but if you think

    if(x == true)
is somehow more "explicit", then surely

    if((x == true) == true)
is even better?

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

If someone is not familiar then they should be encouraged to learn and level up, rather than pulling down everyone else.

Re:Dennis Ritchie on the priorities of && || vs. == etc. (1982) by wruza on Saturday January 06, 2024 @11:25AM (#38892707)
I got little scars from knowing precedences and then switching languages. I also got them from short-testing booleans that later turned into T|boolean. And all these clean just_p’s incrementally evolved into !just_p ? !un_q : t’s. Because I was flying through a mass-change after a day and had no mental capacity to repack the meaning of the previous expression and retain the context of a changeset.

Crystallized syntax is clear, but also extremely fragile, if you take humans into account. We have limits. Everything pushes us to these limits. Any complexity spike that overlaps with secondary complexity or fatigue is above our limits. That’s where we make mistakes.

Re:Dennis Ritchie on the priorities of && || vs. == etc. (1982) by mkbosmans on Sunday January 07, 2024 @04:32AM (#38899830)
The big difference between adding the first `== true` to `if (x)` and adding more is that for a bare `x` you need more context to know whether the expression inside the `if` is of boolean type or something that will implicitly be casted to boolean. With `x == true` you know just looking at the `if` statement that it is a boolean expression. Adding more `== true` does not make it more explicit.
Re:Dennis Ritchie on the priorities of && || vs. == etc. (1982) by 9dev on Saturday January 06, 2024 @04:37AM (#38889956)
If you drag it out of context, sure the first example looks more clear. But there is a difference between Boolean logic and arithmetic, and as soon as you use proper variable names, that becomes evident:

(isAdmin || (canReadDocument && canModifyMetadata)) && accountIsActive

Using parentheses makes the code a lot easier to understand here. All these variables carry state with lots of subtleties. Figuring out the implications of all the different cases becomes a lot easier when the code clearly tells them apart.

Re:Dennis Ritchie on the priorities of && || vs. == etc. (1982) by teo_zero on Saturday January 06, 2024 @05:00AM (#38890075)
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".

Re:Dennis Ritchie on the priorities of && || vs. == etc. (1982) by naitgacem on Saturday January 06, 2024 @07:36AM (#38890933)
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) by MaxBarraclough on Saturday January 13, 2024 @07:48AM (#38979490)
If the purpose of quirky code isn't immediately clear from the context (and if the code can't easily be reworked to make it cleaner), it's a good candidate for commenting.
Re:Dennis Ritchie on the priorities of && || vs. == etc. (1982) by mdbauman on Friday January 05, 2024 @06:38PM (#38886593)
Although I agree, most times where I mix any of these without parentheses I end up having to explain it either in code review or when somebody does a `git blame` a couple months later. Rather than waste everyone's time explaining it, it's easier to just use the parentheses since it's what many/most people expect and everyone else can read it well enough.
Re:Dennis Ritchie on the priorities of && || vs. == etc. (1982) by paulddraper on Friday January 05, 2024 @07:30PM (#38886967)
|| is lower precedence than &&. I memorized that, just like I memorized that + is lower precedence than *.

There are some languages (e.g. shell) where they have the same precedence.

Prettier (JavaScript) adds parens like you suggest automatically.

Re:Dennis Ritchie on the priorities of && || vs. == etc. (1982) by User23 on Friday January 05, 2024 @07:00PM (#38886752)
You’re in good company[1]:

  Do not introduce priority rules that destroy symmetry. 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.
[1] https://www.cs.utexas.edu/users/EWD/transcriptions/EWD13xx/E...
Re:Dennis Ritchie on the priorities of && || vs. == etc. (1982) by thomasahle on Friday January 05, 2024 @07:16PM (#38886876)
This article is a joy to read.
Re:Dennis Ritchie on the priorities of && || vs. == etc. (1982) by Terr_ on Saturday January 06, 2024 @12:54AM (#38888829)
> We don’t want to baffle or puzzle our readers, in particular it should be clear what has to be done to check our argument and it should be possible to do so without pencil and paper. This dictates small, explicit steps.

I feel this justifies why I sometimes write code with lots of temporary variables on their own lines: It's a way to break down the problem, to name each thing (especially when it's not a simple method-call to a correctly-named method) and it also makes it easier to verify the behavior with the average line-by-line debugger or line-by-line debugging easier.

In many cases, such temporary local variables have no negative performance impact, being optimized away.

Re:Dennis Ritchie on the priorities of && || vs. == etc. (1982) by lifthrasiir on Saturday January 06, 2024 @03:40AM (#38889701)
It should be noted that this is not same to using a default order (typically, but not necessarily, left-to-right) in such case. Some languages use a term "non-associative" instead.
Re:Dennis Ritchie on the priorities of && || vs. == etc. (1982) by Terr_ on Saturday January 06, 2024 @12:46AM (#38888791)
Agreed, it's quite justified: If their implicit combined behavior isn't easy-to-read-obvious to the author composing the code, then it's also problematic for any poor future-person (perhaps even the original author) tasked with reading and verifying the code. Checking parens is faster than remembering and applying the knowledge.

Plus the rules may be just different enough in different languages to trip up even those who try to remember them.

Re:Dennis Ritchie on the priorities of && || vs. == etc. (1982) by zzo38computer on Saturday January 06, 2024 @01:22AM (#38888980)
I also do (it also makes it more clearly, in my opinion), as well as with the bitwise operators & and | but sometimes with the bitwise operators the code is written in such a way that the precedence doesn't matter anyways and so I will not need to add parentheses anyways.
Re:Dennis Ritchie on the priorities of && || vs. == etc. (1982) by torstenvl on Saturday January 06, 2024 @02:10AM (#38889207)
Do you know the priority in this?

[ -e "${target}" ] && echo "Getting information about ${target}" && stat "${target}" || echo "Failed to stat file."

EDIT: What about the || die("...") pattern in Perl?

Or the fact that the glyphs in || are visually lower than the glyphs in &&?

Or that "and" comes before "or" in the expression "and/or"?

Re:Dennis Ritchie on the priorities of && || vs. == etc. (1982) by PhilipRoman on Saturday January 06, 2024 @03:40AM (#38889699)
The shell command is very readable.

a && b && c is a common idiom for "stop if any step fails". In the shell language && and || are more like control flow concepts, rather than binary operators.

And a && b || c is a universal "ternary operator" (with one minor deviation) idiom across many languages, not just the shell

Re:Dennis Ritchie on the priorities of && || vs. == etc. (1982) by pavlov on Saturday January 06, 2024 @02:19AM (#38889250)
Shell scripting sucks, but that’s hardly news.

If I really have to touch a bash script, I just assume nothing works like I might expect from proper programming languages despite any surface similarity, and google every construct with sweat drops dripping down my face. ChatGPT has made the process somewhat more tolerable.

Re:Dennis Ritchie on the priorities of && || vs. == etc. (1982) by cm2187 on Saturday January 06, 2024 @03:08AM (#38889520)
I just asked myself the question for SQL's AND and OR this week. Apparently AND takes precedence but I don't know if it is consistent accross all SQL engines. In any case it seems to me that few programers will know anyway, so it is bad practice to not have parenthesis.
Re:Dennis Ritchie on the priorities of && || vs. == etc. (1982) by buserror on Saturday January 06, 2024 @04:55AM (#38890055)
I do the same, not because I don't know the priorities, but because in my 35+ years career, I've seen so many times when cut+paste of partial expression leads to disaster just because it wasn't grouped properly with parenthesis..

Early in my career I erased several megabytes of shared memory on a mini computer, ie DOZENS of users worth of memory just because I was being 'clever' and cut+pasted bits of an expression the wrong way.

Since then, as a rule, sod the priorities, parenthesis it is...

Re:Dennis Ritchie on the priorities of && || vs. == etc. (1982) by dox_shepherd on Saturday January 06, 2024 @08:00AM (#38891076)
This is the best way in my opinion. Sacrifice a second of typing for clarity. I try to do this with expressions in general.