This blog post was originally posted on my blogpost blog at this URL,
and was later migrated to this place. There may be some comments at the original URL.
Lambdabot is an excellent tool to learn to use point-free style (among other things) in Haskell and similar programming langauges. This tool when asked to point-free the given expression often makes heavy use of sections of (.). I personally have hard time reading expressions using those thingies. I thought it’s only a lambdabot thing, which perhaps nobody uses in their own code. Soon I was proven wrong. I saw them being used in several places. Since I wasn’t able to develop an intuition for them and they were apparently used by those who were clearly not bots, I tried to get help from brilliant folks on #haskell IRC channel.
Here is the whole conversation: (Note: It’s from October 3rd.)
I wasn’t satisfied with the answers, and haven’t been able to develop a math-y mind as they suggested. Yesterday I stumbled upon it again, and so tweeted about it. Thankfully @runarorama saw that tweet and provided the following excellent answer:
(f .) is a function that modifies the return type of another function by f.
(. f) is a function that modifies the argument type of another function by f.
That’s a pretty good way to think of and understand expressions that make use of sections of (.). It seems pretty obvious and simple when you’re told it, but it’s really not that obvious, trust me. :-) (You are free to treat that last sentence as me trying to justify my inability to come up with that explanation on my own. :-P)
To be honest, even after receiving that explanation, I don’t feel very comfortable with sections of (.). I tried to come up with simpler combinators before (in October, again), ones that capture common (.) patterns in more meaningful ways, but couldn’t quite manage it. For now, I have just decided not to use sections of (.) in my own code; and to expand them mentally when I encounter them in someone else’s code.
Incidentally I came across Generic.Pointless.Combinators Haskell library this morning. It looks quite interesting, and I look forward to playing with it this weekend.
I will close this short post with a hat tip to concatenative languages which make such composition a no-brainer. For example, both \x e -> a (b x e) and \x e -> a x (b e) become simply b a in Factor.