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