4 ms·
I used to think I needed both, but since picking up Haskell I don't miss for loops at all and I rarely need to use explicit recursion either--now I almost exclu
by kyllo 11y ago
I used to think I needed both, but since picking up Haskell I don't miss for loops at all and I rarely need to use explicit recursion either--now I almost exclusively use higher-order functions like `map`.
- Retra 11y agoWhen I started learning Python, I always used map and filter because they were just how I thought about problems. But there is a certain bit of elegance to being able to write [process(child) for child in node if child is not None] in lieu of map(process, filter(notNone, child)) The functional style makes better use of conceptual primitives, but the imperative style is generally better for documenting. for child in node: if child is not none: # Comment explaining decision. process(child) # Comment explaining more stuff.
- gnud 11y agoI think LINQ got this very nearly right. You can write this LINQ-style from child in node where child != null select process(child) or with extension methods node.Where(c => c != null).Select(process)
- foobarian 11y agoI'm actually a bit scared of using recursion in production (at a web company). It has its place of course, but gratuitous recursive code that could have been written without gives me pause. It's too easy to miss an edge case and end up with a stack overflow, and that can bring down a whole server farm.
- rhaps0dy 11y agoThe first thing you show is a list comprehension [1], and it's still very much functional style, even if it has a "for" in it. Heck, Haskell has pure list comprehensions. [2] [1] https://en.wikipedia.org/wiki/List_comprehension#Python https://en.wikipedia.org/wiki/List_comprehension#Python [2] https://en.wikipedia.org/wiki/List_comprehension#Haskell https://en.wikipedia.org/wiki/List_comprehension#Haskell
- Retra 11y agoOh, I agree. I mentioned it because is the preferred style in Python -- probably because it is so readable. But my points still apply to the loop version.
- codygman 11y agoHaskell (using function composition): map process . filter notNone $ child
- kyllo 11y agoIf node is a list of children that are wrapped in Maybes you could do something like this: map process $ catMaybes node (catMaybes :: [Maybe a] -> [a] - The catMaybes function takes a list of Maybes and returns a list of all the Just values.) https://www.haskell.org/hoogle/?hoogle=catMaybes https://www.haskell.org/hoogle/?hoogle=catMaybes edit: and even if it's not a list, there's a more general implentation of catMaybes for any type that fulfills isSequence here: https://github.com/snoyberg/mono-traversable/blob/master/src/Data/Sequences.hs#L1527 https://github.com/snoyberg/mono-traversable/blob/master/src...
- JadeNB 11y agoOf course you are talking about practical useage, not making blanket theoretical statements, but it may be worth knowing that there are computable functions, if somewhat tortured ones, that can't be computed just by `map`s and `fold`s. See https://en.wikipedia.org/wiki/Primitive_recursive_function#Limitations https://en.wikipedia.org/wiki/Primitive_recursive_function#L... and http://ieeexplore.ieee.org/xpl/articleDetails.jsp?arnumber=6229782 http://ieeexplore.ieee.org/xpl/articleDetails.jsp?arnumber=6... .