[Haskell-cafe] Why is $ right associative instead of left associative?

ajb at spamcop.net ajb at spamcop.net
Sat Feb 4 19:02:52 EST 2006


G'day all.

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
counter-example?

> 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)

or this:

    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.

Cheers,
Andrew Bromage


More information about the Haskell-Cafe mailing list