[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: peasant revolt against DrScheme!



> X-Authentication-Warning: fast.cs.utah.edu: majordom set sender to owner-plt-scheme@flux.cs.utah.edu using -f
> Date: Sat, 27 Jan 2001 12:00:28 -0500 (EST)
> From: Shriram Krishnamurthi <sk@cs.brown.edu>
> Content-Type: text/plain; charset=us-ascii
> Sender: owner-plt-scheme@fast.cs.utah.edu
> Precedence: bulk
> 
> Reini Urban wrote:
> 
> > Even recursion is an advanced topic, and thanksfully nobody is
> > forced to write recursive in lisp/scheme.
> 
> Quick quiz: If you had to teach recursion, what is the first example
> you would use?  (You may give multiple examples, but they must all be
> ones you would cover in the first week of teaching it.)
> 
> Shriram
> 

Factorial, no doubt.  The way it's handled in SICP is particularly elegant,
contrasting the obviously recursive way of writing factorial e.g.

(define (factorial n)
  (if (= n 1)
      1
      (* n (factorial (- n 1)))))

with the tail-recursive way:

(define (factorial n)
  (define (fact-iter n r)
    (if (= n 1)
        r
        (fact-iter (- n 1) (* r n))))
  (fact-iter n 1))

However, this brings up what I consider to be a very interesting issue in
promoting scheme.  I believe that teaching iteration as tail recursion
early on unnecessarily alienates students.  The student says to himself:
"why should I have to write stuff in this weird tail-recursive way which
hurts my brain when in other languages I could just do a simple for loop?"
e.g.

int factorial(int n)
{
    int i;
	int r = 1;

	for (i = 2; i <= n; i++)
	    r *= i;

	return r;
}

Many students are probably never even taught that there are more
conventional iteration constructs in scheme e.g.

(define (factorial n)
   (define r 1)
   (do ((i 2 (+ i 1)))
       ((> i n) r)
	   (set! r (* r i))))

which can be made even simpler using a macro (left as an exercise :-)) e.g.

(define (factorial n)
   (define r 1)
   (for (i 2) (<= i n) (set! i (+ i 1)) ; or define an inc! macro
        (set! r (* r i)))
   r)

Recursion is important when writing functions to handle recursive data
structures (e.g. trees).  It also sometimes, but not always, leads to
cleaner and easier-to-understand programs.  It also typically leads to
programs that have fewer side-effects, are more functionally pure,
etc. etc.  However, very often ordinary iteration is just the most
straightforward way to go, and since scheme supports that as well, why not
take advantage of it?  It's challenging enough getting people to accept a
very unusual syntax; if they think that things that are easy to do in C can
only be done in a weird and (to them) convoluted way in scheme, the battle
is lost before it's even begun.

Mike