<div dir="ltr"><div class="gmail_default" style="font-family:monospace,monospace">I repeat: the short circuit operations are associative,</div><div class="gmail_default" style="font-family:monospace,monospace">so a && (b && c) necessarily has the same value and effects</div><div class="gmail_default" style="font-family:monospace,monospace">as (a && b) && c.  And this is just as true in C as in</div><div class="gmail_default" style="font-family:monospace,monospace">Haskell.  It is equally true in SML and Erlang (which</div><div class="gmail_default" style="font-family:monospace,monospace">use andalso and orelse), Pascal Extended and Ada, OCaml</div><div class="gmail_default" style="font-family:monospace,monospace">and F#, and Unix shells, to mention but a few.</div><div class="gmail_default" style="font-family:monospace,monospace"><br></div><div class="gmail_default" style="font-family:monospace,monospace">Because the operations are associative, the associativity</div><div class="gmail_default" style="font-family:monospace,monospace">of the operators is of no interest.  Associativity is of</div><div class="gmail_default" style="font-family:monospace,monospace">interest only when (a) there is more than one operator at</div><div class="gmail_default" style="font-family:monospace,monospace">the same precedence level or (b) the operation is not</div><div class="gmail_default" style="font-family:monospace,monospace">associative.</div><div class="gmail_default" style="font-family:monospace,monospace"><br></div><div class="gmail_default" style="font-family:monospace,monospace">Your "training as a kid in math" almost certainly did not</div><div class="gmail_default" style="font-family:monospace,monospace">include any discussion of logical operators, and I would</div><div class="gmail_default" style="font-family:monospace,monospace">be astonished if you had been told that</div><div class="gmail_default" style="font-family:monospace,monospace">   a ** b ** c</div><div class="gmail_default" style="font-family:monospace,monospace">was defined to be</div><div class="gmail_default" style="font-family:monospace,monospace">   a ** (b ** c)</div><div class="gmail_default" style="font-family:monospace,monospace">back in 1950-something, or that there is a famous programming</div><div class="gmail_default" style="font-family:monospace,monospace">language where A-B-C-D means A-(B-(C-D)) that is nearly as</div><div class="gmail_default" style="font-family:monospace,monospace">old.  Your "training as a kid in math" probably did not</div><div class="gmail_default" style="font-family:monospace,monospace">include operators which are neither left associative nor</div><div class="gmail_default" style="font-family:monospace,monospace">right associative but have a hidden conjunction, e.g.,</div><div class="gmail_default" style="font-family:monospace,monospace">  a <= b < c</div><div class="gmail_default" style="font-family:monospace,monospace">does not, in a sane programming language (that is, a</div><div class="gmail_default" style="font-family:monospace,monospace">language that is *not* C and didn't copy its blunders),</div><div class="gmail_default" style="font-family:monospace,monospace">means a <= b && b < c (unless it is a syntax error).</div><div class="gmail_default" style="font-family:monospace,monospace"><br></div><div class="gmail_default" style="font-family:monospace,monospace">Ada and SETLX do something interesting.  They put</div><div class="gmail_default" style="font-family:monospace,monospace">conjunction and disjunction at the same level, refuse</div><div class="gmail_default" style="font-family:monospace,monospace">to define an associativity for them, and forbid mixing</div><div class="gmail_default" style="font-family:monospace,monospace">them.  That is, 'p and then q or else r' is simply not</div><div class="gmail_default" style="font-family:monospace,monospace">legal in Ada.</div><div class="gmail_default" style="font-family:monospace,monospace"><br></div><div class="gmail_default" style="font-family:monospace,monospace">Programming languages have done more and weirder things</div><div class="gmail_default" style="font-family:monospace,monospace">with operators than you imagine.  Take nothing for granted.</div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Fri, 12 Apr 2019 at 21:45, Ivan Perez <<a href="mailto:ivanperezdominguez@gmail.com">ivanperezdominguez@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div>Correct me if I'm wrong here.<br></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Fri, 12 Apr 2019 at 05:21, Richard O'Keefe <<a href="mailto:raoknz@gmail.com" target="_blank">raoknz@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div style="font-family:monospace,monospace">How does the right associativity of the short-circuiting</div><div style="font-family:monospace,monospace">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.</div></div></blockquote><div><br></div><div>In pure Haskell, perhaps, but in other languages, I would say no.</div><div><br></div><div>In a language like C, I would expect that:</div><div>- a && b && c be represented in the AST as (a && b) && c</div><div>- The compiler optimizes the implementation of && to short circuit, which is, in some way, using laziness.</div><div><br></div><div>This is not to say that they are right-associative; it's just a compiler optimization.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div style="font-family:monospace,monospace">  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.</div></div></blockquote><div><br></div><div>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.<br><br></div><div>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 `<tt>op</tt>` then it defaults
to highest precedence and left associativity" (Section 4.4.2).</div><div><br></div><div>Cheers</div><div><br></div><div>Ivan<br></div></div></div>
</blockquote></div>