Newsgroups: comp.software-eng,comp.theory,comp.lang.scheme
Path: cantaloupe.srv.cs.cmu.edu!rochester!cornellcs!newsstand.cit.cornell.edu!news.kei.com!simtel!lll-winken.llnl.gov!venus.sun.com!wnoc-sfc-news!kogwy!math-keio!mad
From: mad@math.keio.ac.jp (MAEDA Atusi)
Subject: Iteration and recursion (Re: Style: multiple returns and relatives)
In-Reply-To: srt@zaphod.csci.unt.edu's message of 19 Nov 1995 19:35:29 GMT
Message-ID: <MAD.95Nov24193212@tanzanite.math.keio.ac.jp>
Sender: news@math.keio.ac.jp
Nntp-Posting-Host: tanzanite
Reply-To: mad@math.keio.ac.jp
Organization: Faculty of Sci. and Tech., Keio Univ., Yokohama, Japan.
References: <RMARTIN.95Nov10210926@oma.com> <dclineDHw7yv.Kx1@netcom.com>
	<BLUME.95Nov17183524@zayin.cs.princeton.edu>
	<48o0u1$k51@hermes.acs.unt.edu>
Date: Fri, 24 Nov 1995 10:32:11 GMT
Lines: 73
Xref: glinda.oz.cs.cmu.edu comp.software-eng:39271 comp.theory:14688 comp.lang.scheme:14387

>>>>> "srt" == Steve Tate <srt@zaphod.csci.unt.edu> writes:
In article <48o0u1$k51@hermes.acs.unt.edu> srt@zaphod.csci.unt.edu (Steve Tate) writes:

    srt> Bzzt, wrong.  You just defined factorial, not Fibonacci numbers.

Although there're many ways to write Fibonacci function in Scheme,
most programmers will write either:

    ;;; Style 1 (iterative)
    (define fib
      (lambda (n)
	(do ((i 1 j)
	     (j 1 (+ i j))
	     (k n (- k 1)))
	    ((< k 2) j))))
or
    ;;; Style 2 (tail recursive)
    (define fib
      (lambda (n)
	(letrec ((ifib (lambda (i j k)
			 (if (< k 2)
			     j
			     (ifib j (+ i j) (- k 1))))))
	  (ifib 1 1 n))))

Of course, no one uses exponential order version for any serious
purposes (except for benchmarking).

    srt> Of course, your point is correct that any loop can be turned into a
    srt> tail recursive function.  So what?  That doesn't mean that it's a reasonable
    srt> way to do it, does it?  

You inverted things.  In Scheme, loops are automatically turned into
tail recursions.  Actually, "Style 1" above is internally processed
exactly the same way as "Style 2".

    srt>... Look at your definition of factorial and the
    srt> one below using iteration in C:

    srt>     for (tmp=1, fact=1;  tmp <= n; tmp++)
    srt> 	fact *= tmp;

    srt> You're not honestly going to say that your formulation is cleaner, are
    srt> you?  It looks like you're using recursion just to use recursion...

Formulation?  Hmm... I think we have to use recursion to formally
define meaning of loops.
Why must we have separate primitives for such special case (loops),
when we already have more general framework (recursion)?
Every looping construct in Scheme is therefore a kind of syntax sugar,
or a macro.

    srt> My previous point stands --- if you're thinking recursively, then
    srt> the natural way to write the Fibonacci function is exactly like
    srt> the original poster did it.  And that is terribly inefficient.
    srt> Use recursion where recursion is good, and iteration where iteration
    srt> is good.  What's so hard about that?  Trying to solve every problem
    srt> with one technique just doesn't work...

Re: recursion is terribly inefficient.
It's absolutely wrong.  You're comparing two different algorithms to
calculate Fibonacci numbers.  One is terribly inefficient (exponential
order) and the other is linear.  And both of algorithms are just
recursively defined.

Anyway, which of two programming styles is natural to a programmer
depends on her/his background.  Go ahead and use loop wherever you
want to.  But it's still a recursion from theoretical point of view.
It's true current computers execute tail recursions efficiently.
But it has nothing to do with the choice of the style.  Some prefer
explicit recursion and others prefer syntax sugar.

				--mad
