I repeat: the short circuit operations are associative, so a && (b && c) necessarily has the same value and effects as (a && b) && c. And this is just as true in C as in Haskell. It is equally true in SML and Erlang (which use andalso and orelse), Pascal Extended and Ada, OCaml and F#, and Unix shells, to mention but a few. Because the operations are associative, the associativity of the operators is of no interest. Associativity is of interest only when (a) there is more than one operator at the same precedence level or (b) the operation is not associative. Your "training as a kid in math" almost certainly did not include any discussion of logical operators, and I would be astonished if you had been told that a ** b ** c was defined to be a ** (b ** c) back in 1950-something, or that there is a famous programming language where A-B-C-D means A-(B-(C-D)) that is nearly as old. Your "training as a kid in math" probably did not include operators which are neither left associative nor right associative but have a hidden conjunction, e.g., a <= b < c does not, in a sane programming language (that is, a language that is *not* C and didn't copy its blunders), means a <= b && b < c (unless it is a syntax error). Ada and SETLX do something interesting. They put conjunction and disjunction at the same level, refuse to define an associativity for them, and forbid mixing them. That is, 'p and then q or else r' is simply not legal in Ada. Programming languages have done more and weirder things with operators than you imagine. Take nothing for granted. On Fri, 12 Apr 2019 at 21:45, Ivan Perez <ivanperezdominguez@gmail.com> wrote:
Correct me if I'm wrong here.
On Fri, 12 Apr 2019 at 05:21, Richard O'Keefe <raoknz@gmail.com> wrote:
How does the right associativity of the short-circuiting Boolean operators in any way contradict the way that such operators work in other languages? These operators are associative, so a && (b && c) necessarily has the same value and effects as (a && b) && c.
In pure Haskell, perhaps, but in other languages, I would say no.
In a language like C, I would expect that: - a && b && c be represented in the AST as (a && b) && c - The compiler optimizes the implementation of && to short circuit, which is, in some way, using laziness.
This is not to say that they are right-associative; it's just a compiler optimization.
It has never been the case that all operators in all programming languages were left associative. For addition and subtraction it matters; you don't want a-b+c interpreted as a-(b+c), but not for || and not for &&. My expectation is that these operators should be right associative.
I can't find any reference for logic itself and, because /\ is introduced as associative from the start in propositional logic, it does not really matter. However, my training as a kid in math and the exposure to how I studied to solve (+) left to right (implicitly associating to the left) would have led me to intuitively parse / parenthesize conjunctions with multiple (&&) the same way unless instructed otherwise.
I think this portion of the Haskell Report is also relevant to this intuition in the case of haskell programmers: "If no fixity declaration is given for `op` then it defaults to highest precedence and left associativity" (Section 4.4.2).
Cheers
Ivan