Newsgroups: comp.lang.dylan,comp.lang.lisp,comp.lang.scheme
Path: cantaloupe.srv.cs.cmu.edu!rochester!udel!gatech!nntp.msstate.edu!night.primate.wisc.edu!aplcenmp!hall
From: hall@aplcenmp.apl.jhu.edu (Marty Hall)
Subject: Re: Recursion where iteration would do
Message-ID: <D63xJC.681@aplcenmp.apl.jhu.edu>
Organization: JHU/APL AI Lab, Hopkins P/T CS Faculty
References: <1995Mar23.150306.4307@VFL.Paramax.COM> <3l1r10$2ib@Yost.com> <3l25ju$2ns@Yost.com>
Date: Mon, 27 Mar 1995 16:23:35 GMT
Lines: 51
Xref: glinda.oz.cs.cmu.edu comp.lang.dylan:3883 comp.lang.lisp:17213 comp.lang.scheme:12421

In article <3l25ju$2ns@Yost.com> yost@Yost.com (Dave Yost) writes:

>Using recursion when iteration would do has always bothered me.
>
>I think it has something to do with this:
>  * iteration is simple in that it can only work linearly
>    (unless you muck it up with sufficient conditional code)
>  * recursion is more powerful (and therefore less simple) in that
>    it can iterate over more complex structures (trees, for example)
>Therefore iteration-style code offers prima facie information
>about its level of complexity.

There's some truth to this, especially in Common Lisp where the
compilers do not necessarily optimize tail recursion. On the other
hand, recursion sometimes has the advantage that it is easier to come
back later and add some cases. For instance, consider a naive
factorial-like implementation of exponentiation:

(defun Power (Base Exponent)
  "Reproduce EXPT in case where Exponent is non-negative integer"
  (cond
    ((= Exponent 0) 1)
    (t              (* Base (Power Base (- Exponent 1))))) )

Now, this is no simpler than the looping algorithm. However, when you
notice that X^N can be expressed as (X^2)^(N/2), one additional case
converts the O(N) algorithm to the O(lg N) one below:

(defun Power (Base Exponent)
  "Reproduce EXPT in case where Exponent is non-negative integer"
  (cond
    ((= Exponent 0)  1)
    ((evenp Exponent)(Power (* Base Base) (/ Exponent 2))) 
    (t               (* Base (Power Base (- Exponent 1))))) )

Converting the looping algorithm into one that does repeated squaring
is quite a bit harder, IMHO.

Anecdotes like this prove nothing, of course. However, it has been my
personal experience that recursive algorithms are a bit more likely to
be extensible. In addition, as a purely practical matter, TRACE and
the debugger give more information about recursive algorithms than
iterative ones.  

I guess the point is that everyone needs to be comfortable with both
approaches, and anybody who can only do one or the other is
ill-equipped. I'm certainly not advocating that algorithms always (or
nearly always) be expressed recursively.

					- Marty
(proclaim '(inline skates))
