Re: passing parameters by reference

From: Christopher C. Stacy (cstacy_at_news.dtpq.com)
Date: 11/27/04


Date: Sat, 27 Nov 2004 22:53:51 GMT

Tomasz Grobelny <grotk@poczta.onet.pl> writes:
> Is it possible to modify a(n associative) list (specificaly: add an
> element) passed to a function as parameter (and how)?

There are two answers to your question.

1. Try thinking of it this way: everything in Lisp is passed
   by reference, except that you never de-reference anything.

If you passed in an array, any changes you make to array elements
is seen globally by anyone who has a pointer to the array.
But in Lisp we would never say "pointer to"; we would just
say "passed the array" or "function YYY also has the array".

Passing in a list means passing in a reference to the head
of the list. The caller might have a pointer to some other
part of the list, so you can only make changes on the parts
that you share. For example, you can't add something to the
beginning of the list. But you can splice things into the
middle of the list, or at the end.

(defun foo ()
  (let ((x (list 1 2 3 4)))
    (bar (rest x))
    (reduce #'+ x)))
        

(defun bar (list)
  (setf (elt list 1) 42) ;; Change 3 to 42.
  (setf list nil)) ;; Pointless and does not affect caller.

(foo) -> 49

You mentioned the DELETE function. Carefully read the documentation
for DELETE, and see that it does not necessarily modify its argument.
You are supposed to use its return value.

2. Besides functions, Lisp also has forms that obey different
evaluation rules. For example, the SETQ and SETQ operators
are not functions, and calling them doesn't work the same
way as I described above. In particular, those two forms
do not evaluate their first argument. Rather, the first
argument is a piece of Lisp code, and rather than that
argument being evaluated, they run an analysis on it to
decide what to do with the rest of the arguments.
SETQ expects its first argument to be a symbol, and the
second argument is a value. It considers te symbol to
name a variable, and assigns the value. (The value is
processed using the normal evaluation rules like a
function call would have done).

Users can invent their own arbitrary forms like that
these are called "macros". A macro call looks syntactically
much like a function call, but of course it's really just
plugging some code into its caller. So, for example,
a macro could receive the name of a variable that is
in the caller's scope. When the macro is "expanded",
it produces some code that uses that variable name.
This code occurs in the caller's scope.

So, for example.

(defmacro tweak (list-var new-head)
 `(setq ,list-var (cons ,new-head ,list-var)))

(defun foo ()
  (let ((x (list 1 2 3 4)))
    (tweak x 'abcd)
    (first x)))

(foo) => ABCD

cheers,
Chris



Relevant Pages

  • Re: embarrassingly simple question
    ... I'm completely new to lisp. ... to modify the list passed in. ... You'll need to use a macro to produce that behavior. ... figure out how to fix it. ...
    (comp.lang.lisp)
  • RE: Dynamic filtering into a new range
    ... --The macro posted is a generic one. ... The IF function is applied over the array. ... but I lack the skills to modify it to use in other situations. ... Dim lngCol As Long, lngLastCol As Long ...
    (microsoft.public.excel.programming)
  • Array and Struct Constants in MASM
    ... compile-time array and structure constants. ... Syntax (used as a macro function): ... This macro creates a MASM struct declaration and also creates ...
    (alt.lang.asm)
  • Re: Help end the testing tedium please
    ... The new macro is crashing at: ... The filename and sheet name look fine. ... two arguments needed for "Consolidate". ... the file really were test1 thru test60, would the array statement need ...
    (microsoft.public.excel.programming)
  • Re: modifying array access syntax
    ... >>> possible performance drawbacks for a moment, Common Lisp appears to ... Only horrendous if you don't appreciate what function this notation ... That is, at some level, the difference between an array and a function is ...
    (comp.lang.lisp)