Subject: Re: Reason for let..defun idiom in _On Lisp_ code?
From: rpw3@rpw3.org (Rob Warnock)
Date: Mon, 28 Jun 2004 05:33:41 -0500
Newsgroups: comp.lang.lisp
Message-ID: <OfWdncZDJqeYaULdRVn-ig@speakeasy.net>
Pascal Bourguignon  <spam@thalassa.informatimago.com> wrote:
+---------------
| tayss_temp2@yahoo.com (Tayssir John Gabbour) writes:
| > Here LET surrounds a DEFUN for little obvious reason, which is not
| > explained:
| > 
| > (let ((rpar (get-macro-character #\) )))
| >   (defun ddfn (left right fn)
| >     (set-macro-character right rpar)
| >     (set-dispatch-macro-character #\# left
| >                                   #'(lambda (stream char1 char2)
| >                                       (apply fn
| >                                              (read-delimited-list
| > right stream t))))))
...
| The meaning of this (let (...) (defun ...))  is that rpar is the
| macro-character value of #\) AT THE TIME OF THE DEFINITION of the
| function ddfn.
+---------------

In that case, another way to have done it would have been this:

      (defun ddfn (left right fn)
        (set-macro-character right (load-time-value
				    (get-macro-character #\))))
        (set-dispatch-macro-character #\# left
	                              #'(lambda (stream char1 char2)
	                                  (apply fn (read-delimited-list
						     right
						     stream
						     t))))))

Or, if you know the code's being compiled [so that the LET & FLET
will get inlined], I'd prefer this:

      (defun ddfn (left right fn)
	(let ((rpar (load-time-value (get-macro-character #\)))))
	  (flet ((left-func (stream char1 char2)
		   (apply fn (read-delimited-list right stream t))))
	    (set-macro-character right rpar)
	    (set-dispatch-macro-character #\# left left-func))))


-Rob

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