[Haskell-cafe] Some thoughts on Type-Directed Name Resolution

Gábor Lehel illissius at gmail.com
Fri Feb 3 15:53:54 CET 2012

On Fri, Feb 3, 2012 at 2:37 PM, AntC <anthony_clayden at clear.net.nz> wrote:
> Do people really write code with huge pile-ups of functions prefix upon
> prefix? Wouldn't that be confusing even when it's unidirectional?

Not really. Pipeline-like chains where you apply each function to the
result of the previous one are quite common and readable, whether in
the shell, Haskell, or your 'Yay!!' example. But possibly we aren't
referring to the same thing.

> I've seen
> some examples in other threads mixing dot notation with function composition
> with user-defined operators built with a dot (like >.< ) and a sprinkling of
> parentheses. They were indeed unreadable, but frankly, I don't think that was
> purely down to the dot notation.

Well, yeah. If you want to write confusing code you can certainly do
that. You can do it already. I don't think adding another way to do it
is a huge problem. I think you can expect people to not shoot
themselves in the feet intentionally. What -is- a problem is if you
are forced or encouraged to write confusing code (because there's no
other way to do it or because it's the path of least resistance),
which is why I dislike proposals which make postfix application
mandatory for some purposes, or which make it have different behaviour
from normal prefix application.

> And now that I've found it, I so love:
>    customer.lastName.tail.head.toUpper    -- Yay!

I agree that this is nice, but it only works with single-argument functions.

> I notice that for prefix functions you do sometimes need a bit of trickery to
> deal with partial application and inconvenient order of parameters. Of course
> there's parentheses to help, but there's also a family of combinators,
> especially:
>    ($) -- loose-binding function application
>    (.) -- function composition
> So I'm going to take your post as a challenge: can we build a family of
> combinators for postfix style? The objective is to 'keep up the momentum' left
> to right.
> I've already been using one such:
>    (.$)  = flip ($)          -- looks combinator-ish to me!
>    (.$!) = flip ($!)         -- strict version
>    customer.lastName .$ tail .$ head .$ toUpper    -- Yay.$!

I don't see a benefit here over plain dot...

>> For example, take the filter function from the Prelude:
>> filter :: (a -> Bool) -> [a] -> [a]
>> But for postfix function application, this latter order is the one you want:
>> [1..10].filter even
>> is a lot more intuitive than
>> even.filter [1..10]
> Agreed. Easy. How do you like these?:
>     [1..10] .$ filter even
>     [1..10] .$ filter even .$ sum ^ 2
>     [1..10] .$ filter even .$ foldr (+) 0 ^ 2
> I'm looking at those thinking 'Oh yes! foldr (+) 0 is atomic-ish'.

Oh, well, this looks alright. Hmm.

>> If we restrict this postfix notation
>> to only selecting fields from records,
> Would you like to include 'virtual' fields like fullName or area? Or fst or
> last or middleInitial?

I guess these would be OK. Virtual fields are effectively required to
be single-argument, so you don't encounter the argument-order problem,
and if you can write them equally prefix and postfix then you can
avoid the mix-and-match problem. But this opinion might be obsolete,
see below.

>> So my preferred solution is:
>> - Selecting fields from records can be written (equivalently) using
>> either prefix or postfix notation;
>> - Everything else can be written only with prefix notation.
>> My second-choice solution is to not introduce postfix notation.
> Noted. (And from the above, you won't expect me to agree.) I guess GHC HQ gets
> the final decision. Glad I'm not having to mediate.

If postfix code can be conveniently written using your (.$) combinator
(and presumably its extended family), with no changes required to
existing or future functions, I guess it could all work out. What I'm
afraid of is that introducing postfix notation results in a pressure
to make functions convenient to use with it, and then we eventually
end up in the morass I described. If we can reasonably expect that
having the postfix combinators around will remove that pressure or
that people will resist it, and that we won't end up with a
proliferation of writeIORef-endian functions on Hackage, I guess I
would be okay with it. I'm not sure what we would need to be able to
reasonably expect that.

(Not that me being okay with it is required for anything.)

More information about the Haskell-Cafe mailing list