From: Kevin Gallagher
Subject: Re: mutating params passed by ref
Date: 
Message-ID: <45sook$qrt@kernighan.cs.umass.edu>
·······@trombone.CS.Berkeley.EDU (Kevin Murphy) writes:

> I want to be able to write
>
>   (defun foo (kb)
>     (push '1 kb))
>
> and have the kb argument changed in the caller's environment.
> However, this doesn't happen, even though push is a destructive
> function, and - at least according to the Franz lisp manual -
> lists are passed by reference.

PUSH is not necessarily a destructive operation.  (A destructive
operation is one that modifies an existing data structure.)  In this
case, PUSH reassigns the second argument, the variable KB, but no data
structures are changed.  As others have pointed out, the original list
that KB referred to remains unchanged.

More importantly, I don't think terms like `pass by reference' or
`pass by value' are particularly helpful in understanding lisp
argument passing.  It's easier to simply think of objects being passed
around -- not a `reference', not the `value', but the object itself.
Some types of objects are mutable (conses, arrays, structures, CLOS
instances, etc.), other types of objects are immutable (numbers,
characters, etc.).

If you change a mutable object then all other references to the
object will see the change that you made.  Conversely, if you don't
change a mutable object, but only reassign a local variable so that it
refers to something else (which may itself include the original value
of the local variable) then _no_ other references will be affected.

For most people learning lisp, this is not surprising for data
structures like arrays.  However, lists seem to generate more
confusion.  The principle is the same for both: unless you explicitly
do a destructive operation on an object, all other references to
the object will see the same, unchanged, object.


Kevin Gallagher