Sam Steingold wrote:
> 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?
> How do I get the desired result?
> (declaring i special doesn't change anything)
> Thanks.
The DO loop establishes a single binding for I and side-effects it
each time round the loop, rather than re-binding I. So the I in
the closure you're manufacturing each time is a reference to the
*same* binding, namely the one established by the DO loop.
Here's one way to get the effect you want.
(let ((l (do ((i 0 (1+ i))
(r nil))
((= i 3)
(nreverse r))
(let ((new-i i))
(push #'(lambda () new-i) r)) ) ))
(mapcar #'funcall l))
If you want to confuse your readers, you can replace both occurrences
of NEW-I with I. :-)
--
Gareth McCaughan Dept. of Pure Mathematics & Mathematical Statistics,
·····@dpmms.cam.ac.uk Cambridge University, England.