Hacker News new | ask | show | jobs
by Zak 5066 days ago
Yes, map, reduce and filter feel much more natural to me than explicit loops for their respective use cases. Let's try writing an example in English:

    Give me the items from the collection foo for which the function bar returns true.

    Create an empty collection baz and a counter i with a value of 0. Until i reaches the length of the collection foo, do the following, then increment i and repeat: call the function bar with the element of foo at position i. If bar returns true, append the element to baz. After the loop is complete, return baz.
The for loop is pretty awkward just to express in English, while the filter is straightforward enough that most non-programmers would have a pretty solid understanding of what they'll get.
1 comments

Fascinating, thanks. I would have said that the for-loop is at least somewhat intuitive -- the step-by-step (lather, rinse, repeat) nature resembles the way most instruction sets are written. Not to mention flow charts, which most people have been exposed to at some stage.

Do you have any advice for languages and techniques for getting the necessary exposure to these concepts? I'm not in a position to use FP through work, so I'd need some easy intro and way to practice.

Do you have any advice for languages and techniques for getting the necessary exposure to these concepts?

Functional programming tends to emphasize data flow and leave control flow as an (often hidden) implementation detail. So, I find it’s helpful to think of algorithms in terms of transformations of data rather than series of instructions.

For example, what values do I start with, and are they in (unordered) sets, (ordered) sequences, or something more intricate? Then, what do I want to end up with?

Now, how can I get from one to the other via a series of transformations or combinations of the data? Am I turning one set/sequence/whatever into another, operating on the individual elements? If so, that’s probably some sort of map operation. Am I combining element of a sequence somehow? If I’ve already got a sequence, that’s probably a reduce or something like it. But what if I’ve only got an unordered set? Then maybe I need to impose some ordering first. Can that order be arbitrary, or is there really some implicit order that gets me to working with a well-defined sequence? Maybe I need to combine multiple sequences somehow. If each element in one sequence corresponds to a single element in the other, that’s probably some sort of zip operation. If it’s a many-to-many matching, that might be some sort of nested recursive algorithm that walks each sequence one inside the other, or maybe I can generate an outer product so I’ve got a one-dimensional list of all possible pairs and then do something simpler with that.

After a while, you get to recognise basic underlying data structures like sets, sequences, and trees, and you get to recognise which common operations make sense for each type. You can map just about anything, but to reduce you need a sequence. You can make a sequence from a set by imposing an arbitrary order if necessary. You can make a sequence from a tree in several ways, for example by traversing it in depth-first or breadth-first. And so on.

Sometimes you’ll need to do something that isn’t a convenient, ready-made transformation like a filter or zip, and at that point you start thinking about using recursion to traverse the relevant data structure(s) “manually”. Once you’ve done that a few times, you might start to see new kinds of recurring logic within your code, which you can abstract away into their own higher order functions to join the standard toolbox next to fold and friends.

You can get into all kinds of fun and games with representing effects and controlling the interactions between them as well. However, I’d suggest that if you can start to think of simple problems in terms of things like transforming and combining structured data and then move on to implementing more advanced algorithms by combining the simpler building blocks, that’s probably the best way to get your feet wet without getting out your depth in the early days.

Ruby, especially the standard Array library. Look at stuff like select, each, and whatnot, methods that take a block. Try and write (or rewrite) a toy program you have lying around and make sure you try to use those.

jQuery is another option if you want web-related stuff, esp. http://api.jquery.com/category/traversing/.

Don't thank us for exposing this to you just yet, though. :) You can use this pattern in some mainstream programming languages, but not all of them--- typically it's not idiomatic in Java or C++.

I think there's still a gap between how you're thinking about it and how I am.

Yes, a for loop translates pretty cleanly to a flowchart. It's not hard to understand how it works. The problem is that I'm usually thinking about the result I want in the case of sequence transformations like map and filter, not the process of generating it.