|
|
|
# Proposal: make the $ operator left-associative
|
|
|
|
|
|
|
|
## Arguments in favour
|
|
|
|
|
|
|
|
|
|
|
|
0) $ was introduced as a combinator for function application.
|
|
|
|
Therefore we might expect that whenever we have a function application
|
|
|
|
we can stick a $ in there. But this is not the case. Consider the
|
|
|
|
following expression:
|
|
|
|
|
|
|
|
```wiki
|
|
|
|
f x y
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
There are two applications here and if $ behaved like function
|
|
|
|
application we would be able to write:
|
|
|
|
|
|
|
|
```wiki
|
|
|
|
f $ x $ y
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
But as it is now this expression means something completely different.
|
|
|
|
|
|
|
|
|
|
|
|
(these following points taken from [ Dan Doel's post on the haskell-prime mailing list](http://www.haskell.org/pipermail/haskell-prime/2008-April/002459.html))
|
|
|
|
|
|
|
|
|
|
|
|
1) Anything of the form:
|
|
|
|
|
|
|
|
```wiki
|
|
|
|
f $ g $ h $ x
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
with right associative ($) can instead be written:
|
|
|
|
|
|
|
|
```wiki
|
|
|
|
f . g . h $ x
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
where the associativity of ($) doesn't matter. It's not uncommon to want to
|
|
|
|
peel off the end of such a pipeline to eliminate a point. For the second
|
|
|
|
form, such a translation is:
|
|
|
|
|
|
|
|
```wiki
|
|
|
|
\x -> f . g . h $ x ==> f . g . h
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
However:
|
|
|
|
|
|
|
|
```wiki
|
|
|
|
\x -> f $ g $ h $ x ==> f $ g $ h
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
Is invalid, so one might argue that writing such pipelines with composition is
|
|
|
|
a better habit to get into, as it allows easier cleanup of code in this way
|
|
|
|
(if you like somewhat point-free code, that is).
|
|
|
|
|
|
|
|
|
|
|
|
2) Left associative ($) allows you to eliminate more parentheses. Per [\#1](https://gitlab.haskell.org//haskell/prime/issues/1), any
|
|
|
|
parentheses eliminated by right associative ($) can be eliminated by (.) and
|
|
|
|
a single ($). However, left associative ($) allows, for instance:
|
|
|
|
|
|
|
|
```wiki
|
|
|
|
f (g x) (h y) ==> f $ g x $ h y
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
3) Left associative ($) is consistent with left associative ($!). The right
|
|
|
|
associative version of the latter is inconvenient, because it only allows
|
|
|
|
things to be (easily) strictly applied to the last argument of a function.
|
|
|
|
Needing to strictly apply to other arguments gives rise to things like:
|
|
|
|
|
|
|
|
```wiki
|
|
|
|
(f $! x) y z
|
|
|
|
((f $! x) $! y) $! z
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
Left associative, these are:
|
|
|
|
|
|
|
|
```wiki
|
|
|
|
f $! x $ y $ z
|
|
|
|
f $! x $! y $! z
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
There may be more arguments, but those are the ones I've heard that I can
|
|
|
|
think of at the moment. [\#3](https://gitlab.haskell.org//haskell/prime/issues/3) strikes me as the most likely to bite people (the
|
|
|
|
other two are more stylistic issues), but I suppose I don't know the relative
|
|
|
|
frequency of strict pipelines (f $! g $! x) versus strict applications at
|
|
|
|
non-final arguments.
|
|
|
|
|
|
|
|
## Arguments against
|
|
|
|
|
|
|
|
- This would break a *lot* of code. |