I was heading home one evening down a back road. Much to my surprise, there was a big rig driving down the same small country road. I was immediately irritated by this. "Doesn't he know he can damage the road? It wasn't built for heavy loads. The roads are already bad." I wanted to stop him and tell him off. I quickly dismissed that idea for my own safety. Then I thought of reporting his route to the trucking company or even the Department of Transportation. But then I had a thought that made me decide to drop the whole thing: What if he knew precisely what he was doing? And despite appearances, what if it was actually a well-considered choice?
This particular thought occurred to me because I experience the same kind of push-back from commentators of my posts from time to time. Most of the time the comment seems to assume that the choices I made were due to lack basic knowledge or experience, and they decided to educate me in the correct way. However, I've been at this dev thing nearly 2 decades, and an avid learner the whole time. I certainly don't know everything and continue to accept learning through correction. But the basics... yeah, I got those.
There is often a good reason that I get corrections. Sometimes I make the "wrong" choice on purpose.
Here is an example from my post on Understanding the Fold Operation:
// F# let runChallenge someList = someList |> List.fold update init
This is the way I would write the function in my own code. However, Functional Programming 101 and DRY says I should have written the
runChallenge function like this.
// F# let runChallenge = List.fold update init
This isn't the first time I received a comment that I should have used the latter style. It is shorter and avoids declaring
someList only to immediately pass it through to another function. So why wouldn't I use it? Well, experience. We have an app in production for a couple of years now that is written completely in functional languages. In the process I have experimented with multiple ways of expressing problems. One of them being point-free style as in the second example.
Whenever I come back to point-free code a month later, I noticed that I always have to trace through the implementation. Defining only the function name
runChallenge doesn't tell me anything about it. Then point-free definitions usually mean the implementation uses a bit of function composition internally. All of that makes it unclear at a glance as to which types a function works with, and therefore what kind of behavior is happening.
It is also "fun" trying to explain point-free code to new developers. It reminds me vaguely of explaining Perl code which uses the
$_ variable implicitly. It is a source of confusion and questions. Whereas when the parameter is explicit, I had to type extra characters, but then I don't get a question about it.
Because of these experiences, I generally do not use point-free notation, even though it is the "right" choice on paper. It is simply not the best dev experience in practice (in F# at least). And I'm not the only one who thinks so. (FYI, the speaker is the creator of the F# language.)
There are always exceptions, right? One case for point-free is where I am intentionally making a terse DSL, such as for URL routing.
Fortunately, people cannot hear/read my inner thoughts (maybe Google and FB have something in the works). But unfortunately, they also can't know whether I have made particular choices out of ignorance or well-considered intention. I think most people don't want to read articles that start with a list of assumptions or caveats, so I don't take the time in every article to explain. Consequently, I am not surprised when I receive corrective comments along this line, and I take time to explain at that point.
I suppose the point of this post, dear reader, is encourage you to consider the author and context of the post. Perhaps they have missed something obvious. (I certainly do at times.) Definitely ask questions if you are unsure. But perhaps also give them some benefit of the doubt. If a particular irritant is tangential to the point of the article, maybe it's not worth mentioning. I'm also talking to myself here.
As to the truck driver. I observed his driving behavior as I followed behind him. The way he was driving the truck around corners, it was clear that he was carrying a light load. Then I thought of his alternative routes. The main one was a busy 4-way stop. He probably would have had to wait until a car stopped far enough back for him to make a wide turn. Taking that route would have delayed everyone at the stop. So ultimately I decided that maybe the driver knew exactly what they were doing, and I gave them the benefit of the doubt.