[Haskell-cafe] Why is $ right associative instead of left
ajb at spamcop.net
ajb at spamcop.net
Sat Feb 4 19:02:52 EST 2006
Quoting Tomasz Zielonka <tomasz.zielonka at gmail.com>:
> Probably it was anticipated that right associative version will
> be more useful. You can use it to create a chain of transformations,
> similar to a chain of composed functions:
> (f . g . h) x = f $ g $ h $ x
Of course, if $ were left-associative, it would be no less useful here,
because you could express this chain thusly:
f . g . h $ x
This is the way that I normally express it. Partly because I find
function application FAR more natural than right-associative application,
and partly because I'm hedging my bets for Haskell 2 just in case the
standards committee wakes up and notices that the associativity of $ is
just plain wrong and decides to fix it. :-)
In fact, I'll go out on a limb and claim that ALL such uses of $ are
better expressed with composition. Anyone care to come up with a
> But of course, left associative version can also be useful. Some
> time ago I used a left associative version of the strict application
> operator, which I named (!$).
In fact, I think it's much MORE useful, and for precisely the reason
that you state: it makes strict application much more natural.
Strict application also has the wrong associativity. As it is, $! is
only useful if the _last_ argument of a function needs to be strict. I
find that ordering my arguments in a de Bruijn-like order (which many
experienced functional programmers do unconsciously) results in this
being the least common case.
The last argument of a function is usually the induction argument: it's
almost invariably the subject of a top-level test. The strictness
analyser invariably picks up that the argument is strict. It's the OTHER
arguments you may need to evaluate early.
Suppose you have a function with three arguments, the second of which
needs to be strict. I want to write something like this:
f (g x) $! (h y) $ (j z)
What I have to write is this:
(f (g x) $! (h y)) (j z)
let y' = h y in y' `seq` f (g x) y' (j z)
> Anyway, you can't always remove all parentheses. And why would you want
> to? Everybody is used to them.
I agree. However, sometimes parentheses make things more confusing.
Almost always the best solution is to give the offending subexpression
a name, using "let" or "where". However, the specific case above is the
only one that I've found where this, too, makes things worse.
In summary: There is no good reason to make $ right-associative and at
least one good reason to make it left-associative.
More information about the Haskell-Cafe