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

Pass by reference in LISP



>Date: Tue, 30 Jun 92 15:27:45 -0400
>From: jbk@world.std.com (Jeffrey B Kane)
>To: info-mcl@cambridge.apple.com
>Subject: 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


This is a no-brainer in LISP as well, but the trick here is to realize
that Lisp is fundamentally different from Pascal and C. The closest
thing to what you have would be this:

? (defvar list-1 nil "This is a documentation string")
LIST-1
? (defun test (a-list)
  "tack something onto a list"
  (cons '(add-me) a-list))
TEST
? (setf list-1
      (test (test (test list-1))))
((ADD-ME) (ADD-ME) (ADD-ME))
? 

Don't worry about wasting time and RAM copying lists - CONS does
not copy its arguments.

When programming in Lisp, you would do well to resist the urge to program
in terms of side-effecting global variables and using PROGN all the time.
I know, it's almost as painful as saying goodbye to GOTO, but trust me,
once you get the hang of it, you'll see why it's far superior.