In article <
10e817c1-f4f5-4033...@googlegroups.com>,
paris...@gmail.com wrote:
> Today I was cleaning up some code and made a mistake.
>
> The code was originally like this
> (defparameter *baz* (list 'a #'(lambda()(third *baz*)) 'c))
>
> Now *baz* is bound early enough that the lambda works properly.
The issue isn't when it's bound, it's that it's bound in the same scope
that the variable is looked up in -- they're both in the global scope.
>
> It failed when I moved it into a function:
>
> (defun foo ()
> (let ((bar (list 'a #'(lambda()(third bar)) 'c)))
> (print bar)))
>
> The binding for let doesn't occur until running, so (third bar) is unbound.
No, the issue is that the scope of the binding is the LET body, which
doesn't include the initial value expression.
>
> This can be easily remedied with:
> (defun foo ()
> (let ((bar))
> (setf bar (list 'a #'(lambda()(third bar)) 'c))
> (print bar)))
>
> Are there neater ways to do the same thing?
(defun foo ()
(locally (declare (special bar))
(let ((bar (list 'a #'(lambda () (third bar)) 'c)))
(print bar))))
In Scheme you could do what you want using LETREC, but Common Lisp
doesn't have this. Since it's usually used for defining local
functions, and Common Lisp doesn't use LET for defining local functions
(because of the separate function and value namespaces), we achieve this
using FLET and LABELS -- the latter allows for recursion. But we don't
have a LABELS-equivalent for LET.
--
Barry Margolin,
bar...@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***