[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: something *very* strange (to *me*).
- To: <clisp-list@ma2s2.mathematik.uni-karlsruhe.de>
- Subject: Re: something *very* strange (to *me*).
- From: Bruno Haible <haible@ilog.fr>
- Date: Fri, 3 Oct 1997 18:07:12 +0200 (MET DST)
- >received: from halles.ilog.fr (halles.ilog.fr [172.16.1.96]) by ilog.ilog.fr (8.8.7/8.7.3) with ESMTP id SAA19329; Fri, 3 Oct 1997 18:07:14 +0200 (MET DST)
- In-reply-to: <9710038758.AA875892986@inet.stknhlg.com>
- References: <9710038758.AA875892986@inet.stknhlg.com>
Sam Steingold <sshteingold@cctrading.com> writes:
>
> In CLISP:
>
> (let ((l (do ((i 0 (1+ i)) r)
> ((= i 3) (nreverse r))
> (push #'(lambda () i) r))))
> (mapcar #'funcall l))
>
> ==> (3 3 3)
>
> I would expect (0 1 2)
>
> What is going on?
This is a very unfortunate pitfall in Common Lisp. The #'(lambda () i)
captures the "binding" of the variable i, not its value - so that you
can setf i from within the function. Therefore
(let ((i 0)) (push #'(lambda () ...) l))
(let ((i 1)) (push #'(lambda () ...) l))
and
(let ((i 0)) (push #'(lambda () ...) l)
(setq i 1) (push #'(lambda () ...) l))
are different: in the first case, the two functions operate on separate
i_s, in the second they can interact through the variable i.
Unfortunately, Common Lisp's `do' macro chooses the second alternative.
(For efficiency reasons, I assume.)
> How do I get the desired result?
Instead of
#'(lambda () i)
you write
(let ((i i)) #'(lambda () i))
Looks stupid, but does the trick.
Bruno