[Haskell-cafe] Why are && and || right-associative?
raoknz at gmail.com
Sat Apr 13 10:14:11 UTC 2019
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
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 at gmail.com>
> Correct me if I'm wrong here.
> On Fri, 12 Apr 2019 at 05:21, Richard O'Keefe <raoknz at 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
>> 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).
-------------- next part --------------
An HTML attachment was scrubbed...
More information about the Haskell-Cafe