
Malcolm Wallace wrote:
This style supports multiple operations nicely, especially with combined with the $ operator.
But note that the version with $ is actually longer than the one with nested parens!
Only because I put in the third $, which wasn't necessary, and which most people using this style would probably omit. Without that $, they're the same length. And of course I could make the first one shorter by leaving out some of the whitespace, but I would never recommend that. Character counts are mostly irrelevant anyway -- what matters is ease of reading. To my eye, the version with the $ is slightly easier in this case, but opinions can certainly vary. I think the $ style becomes much easier to read as you (1) add more operations, and (2) start mixing operations (eg, some inserts and some deletes). For example, compare insert 1 $ delete 2 $ delete 3 $ insert 4 $ delete 5 someset and insert (delete (delete (insert (delete someset 5) 4) 3) 2) 1 In the latter style, how easy is it to tell whether 3 is being inserted or deleted? In the former style, it is obvious that 3 is being deleted. Of course, I will freely admit that such examples are fairly rare in real programs.
And where the operands are not statically known, the different orderings do simply come down to foldl/foldr preference:
insert 1 $ insert 2 $ insert 3 $ someSet == foldr insert someSet [1,2,3]
insert (insert (insert someSet 3) 2) 1 == foldl insert someSet [3,2,1]
In some sense the foldl variant is more 'obvious' about the order in which elements are actually inserted.
Yes, I agree that the order of operations in the $ style is somewhat counter-intuitive (in exactly the same way that "foo . bar . baz" is). This rarely seems to be a problem in practice, however. The most common examples where I've seen this style used are things like initializing the dictionary of an interpreter with the "built-ins", in which case you know that none of the keys overlap so the order doesn't matter. -- Chris