Subject: Re: change a global var from a function?
From: rpw3@rpw3.org (Rob Warnock)
Date: Tue, 26 Aug 2003 01:17:31 -0500
Newsgroups: comp.lang.lisp
Message-ID: <BPCdnVcXxu7mZteiXTWc-g@speakeasy.net>
Joe Marshall  <jrm@ccs.neu.edu> wrote:
+---------------
| "Dave" <uni512web@iol.it> 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)))
	     value)

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

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

	 *SOMETHING*
	 > (box-value *something*)

	 NIL
         > (myfunction *something*)

	 T
	 > (box-value *something*)

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

	 #S(BOX :VALUE T)
         > 

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
	 COFFEE 
	 T 
	 13
         > 


-Rob

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