in reply to Re: Re: Is deep recursion bad?
in thread Is deep recursion bad?
In my opinion, though I am known to be biaised towards FP programming, which is lovely to do in Perl, recursion is not so much of a memory hindrance problem when one can manage to produce a tail-call optimized pureFP algorithm.
In such situations, and for non-trivial algorithms only, one may find that the straight FP algorithms are often much more cleaner, clearer and performant, in terms of CPU cycles, than their derecursived iterative counterparts.
Also, it should be added that, apart from trivial algorithms, deriving functionally identical iterative algorithms may often prove to be a hell of a call!
Then when reached, the iterative solutions, when they are correct (try to prove the correctness of such iterative algorithms!), are unfortunately often not only far from being trivial to understand (not to mention to debug and maintain) but also much less efficient, due to the necessity to often simulate within the language external constructs the recursion stack which is otherwise naturally managed internally by the language engine.
Check these facts on the famous simple Hanoi Tower problem !
1. RECURSIVE METHOD (straightforward)
sub hanoi { my ($n, $a, $b, $c) = @_; return if $n < 1; hanoi($n-1, $a, $c, $b); print "Moving plate from $a to $b\n"; return hanoi($n-1, $c, $b, $a); } -- Example of call $ hanoi(8, "A", "B", "C") => 2^8 - 1 moves -- Comment $n is the number of plates (> 0) to move from pole A to pole B using auxiliary pole C The final 'return' allows for a slight tail-call optimization
2. ITERATIVE METHOD (my best solution so far)
## # hanoi n a b c # Without recursivity nor goto. # Franck PORCHER use constant log_2 => log(2); sub hanoi { my ($n, $a, $b, $c) = @_; my $p = 1; my $k; do { if ( $n ) { $p <<= $n; ($b, $c) = ($c, $b) if ($n & 1); $n = 0; } if ( ($p - 1) && ( $p & 1) ){ $k = log(($p ^ ($p + 1)) & ($p + 1)) / log_2; $p >>= $k; ($a, $b) = ($b, $a) if ($k & 1); $n += $k; $p ||= 1; } if ( $p - 1 ) { print "Moving plate from $a to $b\n"; ($a, $b, $c) = ($c, $a, $b); $p++; } } while $p - 1; } -- Example of call $ hanoi(8, "A", "B", "C") => 2^8 - 1 moves
Question: who feels out there that this last iterative version of Hanoi problem is trivial and self-explanatory ?
There are many problem much more complicated than that out there for which we are happy to be able to provide straight purely functional recursive algorithms, easy to write, and easy to prove correct !
Franck PORCHER, PhD
franck.porcher@gmail.com
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re^4: Is deep recursion bad?
by salva (Canon) on Feb 13, 2015 at 13:26 UTC | |
by Anonymous Monk on May 09, 2015 at 11:00 UTC |