4 ms·
It's probably just me, but I found loops much more intuitive than recursions for those non-recursion oriented problems. That is to say that I prefer to use recu
by markus_zhang 5y ago
It's probably just me, but I found loops much more intuitive than recursions for those non-recursion oriented problems. That is to say that I prefer to use recursion ONLY for those are un-intuitive to solve by loops in a trivial way.
- chongli 5y agoGenerally when you learn recursion you also learn about higher order functions. Most of the use cases of loops get replaced with map/filter/fold. What’s left are typically those “unintuitive” problems that need recursion, such as when you’re dealing with trees.
- tester756 5y ago>What’s left are typically those “unintuitive” problems that need recursion, such as when you’re dealing with trees. I always prefer to walk thru trees with e.g stack/queue because it's easier to reason about / debug it for me
- deleted 5y ago[deleted]
- garethrowlands 5y agoTrue enough but worth noting that a good tree should also have map/filter/fold-like operations.
- whateveracct 5y agoI think recursion and loops are hard to read. I rarely even use either anymore.
- jltsiren 5y agoLoops are intuitive and easy to understand, because they are concrete. They can also be cluttered and hard to read due to all the required bookkeeping. For simple loops, I prefer something like map/filter/fold when appropriate. I try to avoid chaining them, because that often turns the code impossible to understand and makes me feel stupid. If the loop can't be modeled naturally as a higher-order function, an iterator-based loop is easier to read than an index-based loop, which is better than tail recursion. With complex loops, there is no way around concrete loops with comments describing the invariants and what each part of the iteration does. Many problems can be modeled naturally with recursion. Such problems are particularly common with graphs. However, you should never use explicit language-level recursion unless you can guarantee that recursion depth will be small. It's easy to get a stack overflow, so recursion should usually mean a loop with an explicit stack of states.
- toast0 5y agoLoops are nice, but after having written enough Erlang, you get used to using foldl and map when they make sense, and recursing yourself when you need to. I can imagine starting with Erlang and learning about loops later and being weirded out. I've grown to sometimes enjoy how a recursive loop looks in code. Sometimes you put the end case first, sometimes you put the end case last, depending on which makes most sense while writing (or perhaps while editing while reading later). With languages with loops and no pattern matching, I'll always write a loop as a loop, if I used one with both, I dunno, there's probably a few loops I'd do as recursion and most would be loops. OTOH, Erlang is certainly functional, but it's very pragmatic as well, there's not a mention of monads, and one tends not to do a whole lot of weird stuff with closures (although you can). Sure, there's a good number of functions that take functions as arguements (which you can do in C anyway), and there are anonymous functions, but you get better error reporting if you use functions with names, so at least I tend to name anything with more than a few lines. I also tend to have very short functions, but that is somewhat influenced by stack traces only having function names and not line numbers when I started 10 years ago.
- Zababa 5y agoRecursion is great for recursive structures, like trees. When you say "a binary tree is either a leaf, or a node which is a value and two binary trees", it's really easy to imagine how you will use a recursive function on it.
- mamcx 5y agoI like functional code, except that because the use of lambdas is awkward to "escape" them: nums.iter().map(|x| if x > 10 break(?)) This little thing is the major problem of functional chains (this is only a toy version of the issue). Because lambdas are inside the scope is hard to make them truly part of the current execution flow. So, sometimes I change a chain of iterators to simpler loops for things like this. IF iterators where part of current scope, it will look far more natural, IMHO...
- HKH2 5y agonums.iter().take_while(|x| x <= 10)
- mamcx 5y agoYeah, I'm aware of the other options, just pointing that the use of lambdas break the flow.
- emi2k01 5y agoRust just standardized `ControlFlow` which would let you pass equivalents of `break` and `continue` as values. x.try_for_each(|y| {...; ControlFlow::Break} )
- mamcx 5y agoYeah, that is cool, and also show the problem :). Internal iterators and/or lambdas are at odds with imperative code. Some guy also yesterday ponder about this stuff: https://www.reddit.com/r/ProgrammingLanguages/comments/pno38l/what_would_a_principled_imperative_language_look/ https://www.reddit.com/r/ProgrammingLanguages/comments/pno38...
- sullyj3 5y agoHaving written Haskell for a few years, the concepts are kind of interchangeable in my mind. I think of recursion as being basically a loop, and a loop as basically the same thing as recursion. To the point where it seems natural to me to name a recursive helper function `loop`. Obviously they're not exactly the same, but with familiarity they can be translated trivially. I think it's really just a matter of prolonged exposure to make recursion seem intuitive.