Subject: Re: how to define a local function
From: rpw3@rpw3.org (Rob Warnock)
Date: Fri, 13 Apr 2007 03:01:18 -0500
Newsgroups: comp.lang.lisp
Message-ID: <kKidnRtTw5JTpYLbnZ2dnUVZ_ompnZ2d@speakeasy.net>
Pascal Costanza  <pc@p-cos.net> wrote:
+---------------
| Rob Warnock wrote:
| > [1] Though as I noted, one could write a LETREC macro
| >     in CL that does it the same way Scheme does. The URL
| >     <http://schemers.org/Documents/Standards/R5RS/HTML/r5rs-Z-H-10.html>
| >     has a reference LETREC macro (in Scheme) that could be
| >     translated to CL fairly easily, I suspect.
| 
| The macro over there tries to remain applicative and keep the order of 
| evaluation unspecified. If you can afford to be less picky, letrec is 
| quite straightforward to implement:
| 
| (defmacro letrec ((&rest bindings) &body body)
|    `(let ,(mapcar #'first bindings)
|       (setq ,@(mapcan #'copy-list bindings))
|       ,@body))
+---------------

Just so, thank you. With that added to one's CL environment,
my original version then works -- unmodified -- in *either*
Scheme or CL:

    > (defmacro letrec ((&rest bindings) &body body)
        `(let ,(mapcar #'first bindings)
           (setq ,@(mapcan #'copy-list bindings))
           ,@body))

    LETREC
    > ((lambda (n)
	 (letrec ((f (lambda (x)
		       (if (<= x 1)
			 1
			 (* x (apply f (- x 1) '()))))))
	   (apply f n '())))
       5)

    120
    > 

+---------------
| If you want to see the bindings in both function and variable 
| namespaces, you can easily do the following as well:
+---------------

But then you would get inconsistences between the Scheme & CL
versions if there were ever an assignment to one of the variables.
So, thank you, but no thank you.


-Rob

-----
Rob Warnock			<rpw3@rpw3.org>
627 26th Avenue			<URL:http://rpw3.org/>
San Mateo, CA 94403		(650)572-2607