4 ms·
Here's a line of code taken from a (Haskell) Game of Life simulation I was writing just a couple of days ago [0]: showGrid (Grid _ ((_,b),(_,b')) arr) =
by crntaylor 14y ago
Here's a line of code taken from a (Haskell) Game of Life simulation I was writing just a couple of days ago [0]:
showGrid (Grid _ ((_,b),(_,b')) arr) =
L.intercalate "\n" $ cut (b'-b+1) $ map toChar $ elems arr
This is the full code to convert a state of the board to a string, ready to be printed to stdout. It consists of a chain of four function applications, which respectively
1. Get the elements of the array as a list (elems)
2. Convert each element to a char (map toChar ... toChar is defined elsewhere - it's also a one-liner).
3. Cut the list into sublists of the correct length (cut (b'-b+1)).
4. Join the lists together into a single string, separating them with newlines (L.intercalate "\n").
Three of the four functions are curried. I contend that without currying by default, it would take more resources (in terms of lines, characters and mental effort) to write this function.
[0] https://github.com/chris-taylor/Life https://github.com/chris-taylor/Life
- taeric 14y agoOf course... I think many would say that your savings in resources came at the expense of readability. Basically, I think this falls dangerously close to Duff's device in the argument space of currying.
- crntaylor 14y agoYour first point is fair. Of course, 'readability' is extremely subjective. It should always be judged in terms of the intended audience for the code - we'd have to ask a Haskell programmer to be sure. Your second point I disagree with completely. Duff's device is non-idiomatic C that relies on oddities of C syntax (fall-through of cases in a switch statement, and the ability to jump into the middle of a loop). My code is reasonably idiomatic Haskell.
- taeric 14y agoApologies, I should have made the second point more on the humor side than not. I should also stress that I don't think this being somewhat difficult to read is really bad. Just saying that I would expect a lot of folks to balk at it.
- tikhonj 14y agoI'm guessing that you don't find this code readable because of the $ operator. Admittedly, if you aren't used to it, it does look weird; however, once you are used to it--and it doesn't take too long--it makes the code readable. In particular, it naturally splits apart the different function calls. So you can look at the parts separately: L.intercalate "\n", cut (b'-b+1), map toChar, elems arr. Now you have a nice little pipeline. Perhaps to somebody without Haskell experience, the version with parentheses would be easier to understand: L.intercalate "\n" (cut (b'-b+1) (map toChar (elems arr))) However, in general, I find the $ version easier to follow. I also think that this version is better than the same code broken up into arbitrary temporary variables. The pipeline is short and clear; adding temporary bindings would just give me more things to keep in my mind at the same time. One way to think about this is that the $ is very similar to the | in bash, just backwards. So in a bash-like pseudocode, this is something like: elems arr | map toChar | cut (b' - b+1) | L.intercalate "\n" Hopefully that clarifies the structure of the code and why that structure is actually very reasonable. Basically, my point is that the given code is clear and simple; chances are you find it hard to read because Haskell is somewhat foreign and not because the given code is particularly complicated or obfuscated. In fact, I think this way of writing the code is clearer than what you would get in most other languages because it forms a very clear sequence of transformations on the input.
- taeric 14y agoMy main point is simply that most of the folks that do not see the benefit of currying, are not likely to be swayed by this. I muddied that by bringing up Duff's device.
- tikhonj 14y agoI suppose that's fair. The core problem is that the benefits of currying depend to some degree on having amenable syntax, and this means that all the examples are going to seem foreign to people.
- taeric 14y agoThis same thought is made ridiculously clear when you try and use closure like structures in java. Especially if you have folks insisting on the @Override nonsense. Compared to languages that make full use of them, where you have to try and look for them to spot them. (Closures, that is.)
- deleted 14y ago[deleted]