|
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. |