[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

RE: Pass by reference in LISP



>I was wondering if someone could save me a lot of work (I've already spent
>a couple of hours trying to get this "simple" thing to work properly).
>I have a function that takes a list as a parameter.  I want to modify the
>actual list that is passed (like nconc and others) but I'm having one hell
>of a time doing so, unless I use a globalally scoped variable.  The idea is 
>easy:
>
>
>(defun test (a-list)
>  "tack something onto a list"
>  (declare (special a-list)) ; I don't think this line is correct
>  (nconc a-list '(add-me)))
>
>(setf list-1 nil)
>(progn (test list-1)
>       (test list-1)
>       (test list-1))
>list-1
>
>>((add-me) (add-me) (add-me))
>
>You get the idea. In pascal or C this would be a "no braier" but in LISP...
>(the reason I want to modify a list is that this list is going to get
>very very big, and I don't want to waste huge amounts of time and RAM
>copying it).
>        Thanks!
>          Jeffrey

You can destructively modify a passed in cons to get the behavior you want. 
The problem that you were having is that you were trying to destructively
modify the atom nil which is not a cons. You also have to be careful about
pointing to quoted structures since you will accidently end up with circular
structures if you aren't careful.

You can do the same thing in LISP that you do in C or Pascal.

Consider the following example:

? (defun test (ls) (rplacd (last ls) (list '(add-me))) ls)
-> TEST
? (let (result)
    (setf result '(nil)) (test result) (test result) (test result) result)
-> (NIL (ADD-ME) (ADD-ME) (ADD-ME))

-Jonathan