0

Can you turn every recursive procedure with a recursive proces from recursive (even tree recursive) to iterative and vice versa (in Scheme)? By changing the way the code is written?

  • please edit to add more words for clarity. repetitions are OK, stylish English that harms clarity is not OK. "matters of elegance are better left to the tailor and to the cobbler", you know. – Will Ness Oct 27 '20 at 16:25
  • but in general, if I'm guessing what you're asking right, yes. look up CPS, defunctionalization, explicit stack on the heap, etc. – Will Ness Oct 27 '20 at 16:28
  • Does this answer your question? [Do iterative and recursive versions of an algorithm have the same time complexity?](https://stackoverflow.com/questions/8532142/do-iterative-and-recursive-versions-of-an-algorithm-have-the-same-time-complexit) – ad absurdum Oct 27 '20 at 21:43

2 Answers2

1

You have to distinguish between a recursive function/procedure and recursive process. Eg. imagine walking a binary tree. That is surely a recursive process since no matter how you implement it you need to backtrack so if you make it iterative you will have some sort of data structure replacing the system stack that is being used in a recursive solution.

Using the same algorithm you cannot transform a recursive process into an iterative one. That is impossible.

However, some algorithms might be replaced by others that does other things. A great example of this is the fibonacci procedure. Here is a tree walk version:

(define (fib-rec n)
  (if (< n 2)
      n
      (+ (fib-rec (- n 1)) 
         (fib-rec (- n 2)))))

And you have probably seen this version whose algorithm just iterates a window of the values from bottom and up to the answer:

(define (fib-iter n)
  (let loop ((n n) (a 0) (b 1))
    (if (zero? n)
        a
        (loop (- n 1) b (+ a b)))))

These are not the same algorithm. A recursive to iterative conversion of fib-rec would be something like this:

(define (fib n)
  (let loop ((jobs '(fib)) (args (list n)))
    (cond ((null? jobs)
           (car args))
          ((eq? (car jobs) 'swap)
           (loop (cdr jobs)
                 (list* (cadr args) (car args) (cddr args))))
          ((eq? (car jobs) 'add)
           (loop (cdr jobs)
                 (cons (+ (car args)
                          (cadr args))
                       (cddr args))))
          ((< (car args) 2) 
           (loop (cdr jobs) args))
          (else 
           (loop (list* 'fib 'swap 'fib 'add (cdr jobs))
                 (list* (- (car args) 2) (- (car args) 1) (cdr args)))))))

This does pretty much the same as fib-rec except it uses an operations list and an argument stack. It is a recursive process but te procedure is tail recursive and thus iterative.

An inheritly iterative process cannot be converted to a recursive one without changeing the algorithm. Think of it as having the fib-iter and rewriting it to a fib-rec. Also since Scheme doesn't have primitive looping constructs except recursion all iterative processes are done with recursion. If you read the reports you'll see that do and other looping constructs is derives syntax and what recursion they turn into.

Sylwester
  • 47,942
  • 4
  • 47
  • 79
0

Yes, definitely. Recursive function have always a breaking condition. Sometimes the breaking condition is about a list which is used-up and thus becomes null from recursive call to next recursive call. In that case, you can handle it via a for-loop over the list. Sometimes the breaking condition is about some number decreasing or sth else - then one could use a while loop to test for the breaking condition.

Gwang-Jin Kim
  • 9,303
  • 17
  • 30
  • Thank you. And from iterative to recursive? – Tryer outer Oct 27 '20 at 21:14
  • Well if the iteration is over a loop which is used-up or a counter which reaches a certain threshold, one can set the breaking condition of the recursion in such way that it tests for reaching of the limit (= limit counter) or end of list `(null lst)`. And when calling the next recursion call dlminish/enhance counter by the counting step or `(cdr lst)`. – Gwang-Jin Kim Oct 29 '20 at 13:37
  • If the iteration is a while loop, then the while breaking condition becomes the recursion breaking condition. – Gwang-Jin Kim Oct 29 '20 at 13:41