Subject: Re: change a global var from a function?
From: (Rob Warnock)
Date: Tue, 26 Aug 2003 01:17:31 -0500
Newsgroups: comp.lang.lisp
Message-ID: <>
Joe Marshall  <> wrote:
| "Dave" <> writes:
| > Is it possible to change a global var. passed as parameter?
| Lisp is a call-by-value language.
| > I don't know the way to do it (in Lisp).
| There are 3 ways I can think of:
|     1.  The value of a global variable is stored in the symbol value
|         cell.  Pass the quoted name of the symbol:
|     2.  Write myfunction as a macro rather than a function:
|     3.  Pass a `setter' thunk:

      4. Implement the global variable as a object within which the
         value can be "boxed", rather than as the naked value itself.
         Then you can change a slot in the box, rather than change the
         global variable itself. Obvious candidates for implementing the
         "box" type in Lisp: a cons; a one-word structure; a one-word
         vector, a one-slot class, etc. Leaving cons as an exercise for
         the reader, let's use a structure [note: since we only have
         one slot, a BOA constructor is slightly more convenient to use,
         though slightly more complicated to define]:

	 > (defstruct (box (:constructor make-box (value)))

	 > (defun myfunction (box)
	     (setf (box-value box) t))

	 > (defvar *something* (make-box nil))

	 > (box-value *something*)

         > (myfunction *something*)

	 > (box-value *something*)

	 > *something*		; Let's "cheat" and look under the covers...


Note that this variation *does* work with lexical variables, too:

	> (let ((x (make-box 'coffee)))
	    (print (box-value x))
	    (myfunction x)
	    (print (box-value x))
	    13)		; Avoid confusing printed things with return values


Rob Warnock, PP-ASEL-IA		<>
627 26th Avenue			<URL:>
San Mateo, CA 94403		(650)572-2607