Path: utzoo!utgpu!water!watmath!clyde!bellcore!rutgers!mit-eddie!uw-beaver!cornell!oravax!klapper From: klapper@oravax.UUCP (Carl Klapper) Newsgroups: comp.lang.lisp Subject: Re: Amusing Code Summary: Copy, of course Message-ID: <450@oravax.UUCP> Date: 24 Aug 88 14:25:37 GMT References: <389@soi.UUCP> Organization: Odyssey Research Ass., Ithaca NY Lines: 43 In article <389@soi.UUCP>, alex@soi.UUCP (Alex Zatsman) writes: > It took me and few of my friends a while to figure out > seemingly strange effect of TEST-STACK below. I thought > other people will find it amusing too: > > (defvar *Stack*) > > (defun Push-Object (Object) (push Object (car *Stack*))) > > (defun Init-Stack () (setf *Stack* '((:Bottom-Frame)))) > > (defun Test-Stack () > (Init-Stack) (print *Stack*) > (Push-Object 11) (print *Stack*) > (Init-Stack) (print *Stack*) (values)) > The fix is to set the variable to a copy of the list (tree, structure. etc.) which you intend to initialize it to. The copy should be new to whatever level you intend to alter the variable. In this example, (defun init-stack () (setf *stack* (copy-list '((:bottom-frame))))) should be sufficient. However, if the *stack* is "empty", then (car *stack*) would still point to the list (:bottom-frame) in the definition of init-stack and (setf (caar *stack*) ':the-pits) would change that definition to: (lambda-block init-stack () (setf *stack* (copy-list '((:the-pits))))) To avoid this, init-stack should be defined thus: (defun init-stack () (setf *stack* (copy-tree '((:bottom-frame))))) Carl Klapper Odyssey Research Associates, Inc. 301A Harris B. Dates Drive Ithaca, NY 14850 klapper%oravax.uucp@cu-arpa.cs.cornell.edu *** If you wish to make a signature, please hang up and dial again. ***