From: Pierre Vachon
Subject: Advice on recursion?
Date: 
Message-ID: <1992Jul23.192749.129@cerberus.ulaval.ca>
Hi,

Concerning recursive procedures, I would like to know the following:

  Are there disadvantages to using 'labels' like this:

   (defun foo (arg)
     (let ((...))

       (labels ((recursive (arg1 arg2)
                         (body)))
         (recursive 'foo 'bar))))

I know it works, and I like the fact that it's 'clean',
since the alternative would be to DEFUN the recursive part
and even require some special variables, which the LET in
the previous example helps me avoid...

(Of course, the recursive function is only used by FOO,
which is why I like to avoid defunning (!) it on Top Level...)

So, how do YOU 'recurse'...?


Pierre Vachon            Laboratoire de vision et systemes numeriques
······@gel.ulaval.ca     Universite Laval, Quebec, Canada.

From: Barry Margolin
Subject: Re: Advice on recursion?
Date: 
Message-ID: <14nf16INN7m0@early-bird.think.com>
In article <····················@cerberus.ulaval.ca> ······@chicoutimi.gel.ulaval.ca (Pierre Vachon) writes:
>  Are there disadvantages to using 'labels' like this:
>   (defun foo (arg)
>     (let ((...))
>       (labels ((recursive (arg1 arg2)
>                         (body)))
>         (recursive 'foo 'bar))))

That's precisely what LABELS is for: defining recursive or
mutually-callable local functions.  Presumably the body references ARG
and/or the variables bound by the LET, which is why you don't want to use a
global function definition (you would have to pass them as additional
arguments in that case).
-- 
Barry Margolin
System Manager, Thinking Machines Corp.

······@think.com          {uunet,harvard}!think!barmar
From: Simon Leinen
Subject: Re: Advice on recursion?
Date: 
Message-ID: <SIMON.92Jul24122911@liasg1.epfl.ch>
In article <····················@cerberus.ulaval.ca>
······@chicoutimi.gel.ulaval.ca (Pierre Vachon) writes:

     Are there disadvantages to using 'labels' like this:

      (defun foo (arg)
	(let ((...))

	  (labels ((recursive (arg1 arg2)
			    (body)))
	    (recursive 'foo 'bar))))

This is exactly what I use most often.  The main drawback I see is
that you typically cannot trace the internal function if it
misbehaves.  Maybe some Lisps have an extension that permits (TRACE
(LABELS FOO RECURSIVE)) or something, but I don't know any.

Decent Lisp compilers of course optimize a tail recursion to a loop.
Good compilers also integrate the internal function into the caller,
in which case the LABELS version is always as efficient as an explicit
loop construct (at least Lucid and CMU CL can claim this, I believe).

So in the cases where the recursive version seems more natural (which
depends a lot on the observer), there is no reason to sacrifice
clarity for speed anymore, if you assume a state-of-the-art compiler.
-- 
Simon.