4 Feb 15:52
Why is $ right associative instead of left associative?
Brian Hulley <brianh <at> metamilk.com>
2006-02-04 14:52:20 GMT
2006-02-04 14:52:20 GMT
Hi -
In the Haskell98 report section 4.4.2 $ is specified as being right
associative. This means that f $ a0 a1 $ b0 b1 would parse as f (a0 a1 (b0
b1)) which seems rather strange to me. Surely it would be much more useful
if $ were defined as left associative so that it could be used to separate
the args to f?
Does anyone know why this strange associativity was chosen?
Thanks, Brian.
(The reason I'm asking is that I'm working on the syntax of a language
similar to Haskell but which uses layout to allow expressions like:
f #$ -- can be followed by an explicit
block or layout block
a0 a1
b0 b1
which is sugar for (f $ a0 a1) $ b0 b1 ie f (a0 a1) (b0 b1) ) and I was
surprised to discover that the parentheses are needed for the most obvious
reading)
Best regards
Tomasz
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



RSS Feed