Barry Margolin
8/6/2015 2:18:00 AM
In article <8737zxp48r.fsf@rubybox.drb27.me>,
David Bradshaw <user@foo.bar> wrote:
> Would someone please help this newbie? I'm writing some Common Lisp to
> play a game of BlackJack, and I've encountered an effect I don't
> understand. The following code attempts to reduce the code down to a
> minimum required to demonstrate the effect:
>
> ------------------------------------------------------------------------------
> -
> (defvar *global-var* '( ( :lst . (1 2 3))))
>
> ;; Takes the first item from the list at :lst in the source
> ;; and pre-pends it to the list at :lst in the destination
> (defun my-peek (source destination)
> (setf (cdr(assoc :lst destination))
> (cons (car(cdr(assoc :lst source))) (cdr(assoc :lst destination))))
> )
>
> ;; Test run of my-peek.
> (defun test-my-peek ()
> (let ( (lcl '( ( :lst . (1 2 3) ) ) ))
> (my-peek *global-var* lcl)
> (format t "lcl=~a~%" lcl)
> ))
> ------------------------------------------------------------------------------
> -
>
> The intention of my-peek is to look at the first element of a list, and
> insert its value at the head of a second list (both contained within an
> alist, referenced by :lst).
>
> At the first run of test-my-peek, the code seems to work. yielding:
> lcl=((LST 1 1 2 3))
>
> However, if I run the code again in the same interactive shell, I get a
> different answer:
> lcl=((LST 1 1 1 2 3))
>
> It appears that the test-my-peek function has remembered its new value
> after the first call, and does not get reset by the let binding on the
> second call.
>
> Why doesn't test-my-peek give the same answer each time?
You're modifying the conses that are part of the function definition, so
that modifies the function itself.
This is why you're not supposed to use destructive functions on
literals. Change your function to:
(let ((lcl (list (cons :lst (list 1 2 3)))))
...)
and you'll get a fresh list every time you call it.
--
Barry Margolin, barmar@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***