5 ms·
Point-Free style: What is it good for?
- Tichy 17y agoI am not convinced (.^) = (.) . (.) is supposed to be more readable than (.^) f g x y = f (g x y) ? I don't know Haskell, but even so. I think there might be exercises with a better benefit.
- aerique 17y agoThe former is definitely more suggestive.
- Tichy 17y agoProgramming in balance with Yin and Yan :-)
- tetha 17y agoOne might say: You used a drill to get a nail into the wall. Neither the drill, the nail nor you liked it. You concluded that the drill is generally bad. I concluded that I cannot use a drill if I need a hammer. :)
- Tichy 17y agoHow do you mean? I just quoted from that web site... So you are saying their example for Point Free Programming was bad?
- tetha 17y agoYes, that was my point. That example of point free programming is just bad and confusing, as you pointed out. On the other hand, if I try to keep my functions and methods small, I frequently have to write methods which just apply a function to all elements of a collection. In a point free style, I can just write manyFoo = map foo And that's it. No loop, no recursion, no boundary issues, no clutter, just the statement 'this applies foo to everything in a list'. Similar things work for other nicely curry-able problem statements. Imagine you have a higher-order-function traverse which takes two functions, and uses them to transform a binary tree to a value (applying the first higher order function in order to combine the left and right results of a tree and and the other function to turn leaves into values) Now you can define: treesum = traverse + toNum preorder = traverse ++ toList And so on. Overall, the best advice I had about point-free style was: "Try to refactor your code to the form "f x = g x" and remove the x, if the refactoring can be done in a painless way". If you apply this, the drill drills well :)
- deleted 17y ago[deleted]
- hristov 17y agoFirst I would like to say that I am only learning Haskell, and have done nothing but toy programs thus far. But the point free style is something that I really do not like about Haskell. It makes code much more complicated for the dubious benefit of saving a couple of keystrokes. For example, take the code from the article: This is without point free style: sum xs = foldr (+) 0 xs And this is with: sum = foldr (+) 0 You have saved a total of 4 keystrokes. And made that line of code look really weird and hard to understand. Thus, now when you look at code you cannot say at first glance how many arguments a function takes. The second line of code looks like sum takes 0 arguments. But you have to look more carefully at the definition of the function, and see that it uses foldr, and know that foldr takes three arguments, but here only two are defined, and then you figure out that someone is using point free style and then you figure out that sum, actually takes one argument that must be a list. And this of course, is a simple example. Here we have a big clue in that the function is defined with zero arguments, and most functions take at least one argument, therefore the function probably uses the point free notation. But for a more complex and longer function, the point free style can very easily confuse someone reading the code. So yeah, I think point free style is one of these annoying features of Haskell, that seem to be put in so that users of Haskell can pat themselves on the back and feel like they are very smart. But in the end it does not add much to the language and makes it much less accessible.
- mbrubeck 17y agoOnce you're used to the idiom, I find point-free style at least as easy to read as pointful. "Thus, now when you look at code you cannot say at first glance how many arguments a function takes." In Haskell I generally look at the type signature - explicit or inferred - to see what a functions' arguments are. I find this style is actually more beneficial for larger-scale examples than smaller ones. For example, if you have a memoizing combinator, most people would not find it odd at all to write: fast_factorial = memoize factorial instead of: fast_factorial xs = (memoize factorial) xs The key to point-free style is to think of all functions as potentially acting like combinators, and being modifiers for other functions.
- hristov 17y ago
- mbrubeck 17y agoI just like point-free style because it leaves me with fewer things to name, and fewer choices to make. Placeholder names like "xs" are just noise. The "x" has no meaning here: double x = 2*x So I'd rather write it like this: double = (2*) Similarly, there's no need to introduce an arbitrary name like "input" or "numbers" for this function (part of a Project Euler solution): highestProduct = maximum . map product . concat . map (groupsOf 4)
- camccann 17y agoFrom the comments, an alternate form of the (.) . (.) operator: foo = fmap fmap fmap Nothing says "welcome to Haskell!" like an inscrutable pile of fmaps. Oh, pointless style, how beautiful you are. In all seriousness, though, there are a lot of cases where a pointless--er, "point-free"--style is actually clearer and more comprehensible, typically when you're writing functions intended to be used as combinators. Similarly, applicative style sometimes looks a lot cleaner than using do notation.
- how_gauche 17y agoI often use this algorithm: 1. write a function in pointed style 2. run it through pointfree 3. is it shorter/easier to read? then use pointfree's definition This is really a personal shortcoming though because after 20+ years of writing code in "standard" languages my brain is sufficiently warped that I'm not always able to think of the short and clear solution without "grinding the gears".