Skip to main content
10 events
when toggle format what by license comment
Jan 4, 2018 at 0:40 comment added leftaroundabout @8bittree I didn't really intend to single out tail recursion. As J_mie6 argued, general recursion might be what should be considered analogous to GOTO. However, and that's where I'm coming from here, well-written non-tail- recursive code tends to not be such ”pathologically recursive”. On the contrary, functional programmers like to lay out their code in such a way that the defining equations almost spell out the invariants. But this is not enforced by the recursion mechanism per se (unlike with loops, which do constrain the amount of nonsense the programmer can commit).
Jan 3, 2018 at 23:08 comment added 8bittree @leftaroundabout That raises some questions, such as: Why do you think GOTO is bad? (To be clear, I'm not making any claim here on whether it's good or bad. I just want to know your reasoning.) Why do you single out tail recursion, and not include recursion in general, tail calls in general, or function calls in general (or do you include some or all of those, if so, why?)?
Jan 3, 2018 at 17:27 comment added Doval @J_mie6 The recursive equivalent of your "traditional for loop" also has a start, an end, and a deterministic step, and it's easy to show through induction that it'll stop.
Jan 3, 2018 at 12:19 comment added leftaroundabout ... As for folds: you're right, a traditional fold (catamorphism) is a very specific kind of loop, but these recursion schemes can be generalised (ana- / apo- / hylomorphisms); collectively these are IMO the proper replacement for imperative loops.
Jan 3, 2018 at 12:19 comment added leftaroundabout @J_mie6 the reason I consider tail recursion more as a GOTO is that you need to do fiddly bookkeeping of what arguments in what state are passed to the recursive call, to ensure it actually behaves as intended. That is not necessary to the same degree in decently written imperative loops (where it's pretty clear what the stateful variables are and how they change in each iteration), nor in naïve recursion (where usually not much is done with the arguments, and instead the result is assembled in a quite intuitive way). ...
Jan 3, 2018 at 11:05 comment added J_mie6 cont: By that I mean that a fold has a deterministic number of iterations. For any given list, you know exactly how many iterations that "loop" takes. So a fold is like a traditional for loop (in the sense that it has a start, an end and a deterministic step), and a tail recursive function is like a while loop, where it is undecidable now long it takes to compute. In terms of raw power then, the unrestricted recursion is the real GOTO
Jan 3, 2018 at 11:02 comment added J_mie6 @leftaroundabout I'd disagree actually. I'd say tail recursion is more constrained than a goto, given the need to jump to itself and only in tail position. It is fundamentally equivalent to a looping construct. I'd say recursion in general is equivalent to GOTO. In any case, when you compile tail recursion it mostly just boils down to a while (true) loop with the function body in where early return is just a break statement. A fold, whilst you are correct about it being a loop, is actually more constrained than a general looping construct; it is more like a for-each loop
Jan 3, 2018 at 10:28 comment added leftaroundabout @JörgWMittag I'd rather say tail recursion is the functional equivalent to GOTO. (Not quite as bad, but still pretty awkward.) The equivalent to a loop, as Jules says, is a suitable fold.
Jan 3, 2018 at 8:15 comment added Jörg W Mittag Yep. The functional equivalent to a loop is tail-recursion, and the functional equivalent to a conditional is still a conditional.
Jan 3, 2018 at 7:41 history answered Euphoric CC BY-SA 3.0