Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is the $! operator right-associative?

I'm just learning Haskell and I'm still not entirely clear on when and how strict evaluation is forced

When I want a function to evaluate its arguments strictly I find myself writing

((f $! x) $! y ) $! z

which seems weird. Shouldn't $! be left-associative so I could write

f $! x $! y $! z

and have it do what I want?

Am I completely misunderstanding the $! operator?

like image 713
dspyz Avatar asked May 09 '14 17:05

dspyz


People also ask

What does it mean for an operator to be right-associative?

The right-associativity of the = operator allows expressions such as a = b = c to be interpreted as a = (b = c) . In C++, the assignment a = b is an expression that evaluates to the same value as the expression a , with the side effect of storing the R-value of b into the L-value of a .

Why is conditional operator right-associative?

The operator = is right-associative, which means that a = b = c is equivalent to a = (b = c) , as opposed to (a = b) = c . Associativity has nothing to do with the order of evaluation. "Associativity has nothing to do with the order of evaluation." Well, unless all the operators have the same precedence.

Why associativity of * is from left to right?

Associativity can be either Left to Right or Right to Left. For example: '*' and '/' have same precedence and their associativity is Left to Right, so the expression “100 / 10 * 10” is treated as “(100 / 10) * 10”. 1) Associativity is only used when there are two or more operators of same precedence.

Is power operator right-associative?

The ** operator follows normal mathematical conventions; it is right-associative: In the usual computer science jargon, exponentiation in mathematics is right-associative, which means that xyz should be read as x(yz), not (xy)z.


2 Answers

It's to mirror the fixity of $. You could make a very good case for both $ and $! having the wrong fixity.

like image 66
augustss Avatar answered Sep 22 '22 13:09

augustss


Argument against

I found a proposal from 2008 in haskell-prime to make the $ and $! operators left-associative:

https://ghc.haskell.org/trac/haskell-prime/wiki/ChangeDollarAssociativity

There is only one argument against the proposal: "This would break a lot of code".

Arguments in favour

Instead, there are given four arguments in favour of left-associative ($), the last one being the same as yours, and considered the most important. They are, in short:

  • 0) given the expression f x y, with two applications, we would be able to write f $ x $ y

  • 1) now, with right associative ($), we can write f . g . h $ x as f $ g $ h $ x,

    however: \x -> f $ g $ h $ x ==> f $ g $ h is invalid,

    so that writing such pipelines with composition is better, as it allows easier cleanup of code

  • 2) Left associative ($) allows you to eliminate more parentheses, in addition to the ones eliminated with (.), for instance:

    f (g x) (h y) ==> f $ g x $ h y

  • 3) your argument: the right associative version of $! is inconvenient because of giving rise to things like: ((f $! x) $! y) $! z instead of f $! x $! y $! z

Conclusion

I give support to use the better left-associative version of application operators redefining them at the beginning of our code, like this:

import Prelude hiding (($), ($!))

infixl 0  $, $!
($), ($!) :: (a -> b) -> a -> b  
f $  x =         f x
f $! x = x `seq` f x
like image 26
enrique Avatar answered Sep 22 '22 13:09

enrique