Subject: Re: CL idiom for Scheme's named let
From: (Rob Warnock)
Date: Sat, 26 Nov 2005 05:25:14 -0600
Newsgroups: comp.lang.lisp
Message-ID: <>
Wade Humeniuk  <> wrote:
| It is/was my undestanding that a invoking the name in a named let
| resulted in a non-conditional jump (with no expectation that the
| jump will return a value). Thus ordinary recursion could not be done.

Sorry, that's incorrect. The name in a named LET is bound to an
ordinary Scheme procedure, just as if a LETREC [or LABELS, in CL]
had been used [so that the bound name is visible within the
procedure body]. See R5RS Section 4.2.4 "Iteration":

    "Named let" ... has the same syntax and semantics as ordinary let
    except that <variable> is bound within <body> to a procedure whose
    formal arguments are the bound variables and whose body is <body>.
    Thus the execution of <body> may be repeated by invoking the procedure
    named by <variable>.

That is:

    (let foo ((arg1 init1)
	      (argN initN))

is *identical* to [and in some Scheme implementations may simply
macroexpand to]:

    (letrec ((foo (lambda (arg1 ... argN)
      (foo init1 ...initN))

Or in CL:

    (labels ((foo (arg1 ... argN)
      (foo init1 ...initN))

| So for the following simple factorial example is invalid:
| (let fact ((n 10))
|     (if (<= n 2) 1 (* n (fact (1- n))))

No, that works just fine, once you fix the bug in it!  ;-}  ;-}

    > (let fact ((n 10))
        (if (<= n 1) 1 (* n (fact (1- n)))))

Similarly, multiple self-calls within the body also work:

    > (let fib ((n 10))
	(if (<= n 1) 1 (+ (fib (- n 1)) (fib (- n 2)))))


Rob Warnock			<>
627 26th Avenue			<URL:>
San Mateo, CA 94403		(650)572-2607