From: Spandan Choudury
Subject: MULTIPLE variables' modification from a sub-function.
Date: 
Message-ID: <1992Jun3.145657.19568@ucunix.san.uc.edu>
Another easy question:
  
For codes of the form:

  (defun f1 (aa)
      (setq aa 5)
  )
  (defun test-f1 
      (setq a 10)
      (f1 a)
      a         ;; X
  )

"test-f1" will expectedly return a 10 (and not a 5, though a call to "f1" is
made). What can be the simplest way of updating a (to 5) in step "X" when
"test-f1" is called (using a modified "f1") ? In other words, I am looking for
the simplest way of updating the value of a variable in one function (eg. 
"test-f1") by a call to another function (eg. "f1", which is to be modified) 
from it. My main purpose is to call (other) functions from one main function to
work on variables on the main function, and be able to use the *updated* values
of the variables when control is returned to the main function.

Note: In my work, I am *not* calling another secondary function from the 
primary function with just 1 variable as the (changing) argument. I need to 
use a function containing *more than 1 arguments* as variables from the main 
function that all get supposedly modified in that single secondary function. 
(Therefore, I cannot use simple statements like (setq a ( f1 a)) in the 
primary function for the update purpose.)

Please mail me your responses. Thanks.

     --Spandan Choudury

From: Richard A. O'Keefe
Subject: Re: MULTIPLE variables' modification from a sub-function.
Date: 
Message-ID: <11460@goanna.cs.rmit.oz.au>
In article <·····················@ucunix.san.uc.edu>,
········@ucunix.san.uc.edu (Spandan Choudury) wants to pass
several "variables" to a Lisp function so that the function
can modify the "variables" and the caller will see the change.

The preferred way is to simulate the "pass by value result" argument
passing method of Algol W, which Fortran compilers and Ada compilers
are allowed to use for intent in out parameters.  So you would just
pass the current values of the parameters in as usual, and the function
would return the updated values using (values v1 ... vn).  The caller
would pick up the results using multiple-value-setq or multiple-value-bind.

Another method is to imitate Pop-2 and ML and introduce a data structure
to behave like a "variable".  Example code:

(defmacro make-box (contents)
    `(cons ,contents '()))

(defmacro contents (box)
    `(car ,box))

(defun test ()
    (let ((a (make-box 1))
	  (b (make-box 2)))
	(incf (contents a))
	(decf (contents b))
	(rotatef (contents a) (contents b))
	(list (contents a) (contents b)) ))


Now you can pass "variables" to a function like so:
	(let ((a (make-box 42)))
	    (foo a)
	    (bar (contents a)) )
where
	(defun foo (x)
	    (incf (contents x)))
This will pass 43 to bar.

More to the point, my experience with students has been that a desire
to have a function which modifies an argument means that they are not
"thinking in Lisp" yet.  It's amazing how Fortran argument lists shrink;
an example I was looking at recently has 5 arguments in Fortran 77 but
needs only 1 in Lisp (the IFLAG argument vanishes because Lisp has a
better way to report errors, and the remaining 4 arguments are needed
to define an array in Fortran).  So I am rather puzzled as to why anyone
would need even one modifiable argument in Lisp, let alone several.

-- 
You can lie with statistics ... but not to a statistician.
From: Ted Dunning
Subject: Re: MULTIPLE variables' modification from a sub-function.
Date: 
Message-ID: <TED.92Jun4142933@lole.nmsu.edu>
In article <·····@goanna.cs.rmit.oz.au> ··@goanna.cs.rmit.oz.au (Richard A. O'Keefe) writes:


   In article <·····················@ucunix.san.uc.edu>,
   ········@ucunix.san.uc.edu (Spandan Choudury) wants to pass
   several "variables" to a Lisp function so that the function
   can modify the "variables" and the caller will see the change.

   The preferred way is to simulate the "pass by value result" argument
   passing method of Algol W, which Fortran compilers and Ada compilers
   are allowed to use for intent in out parameters.  So you would just
   pass the current values of the parameters in as usual, and the function
   would return the updated values using (values v1 ... vn).  The caller
   would pick up the results using multiple-value-setq or multiple-value-bind.



rok is absolutely correct here, but it should be pointed out that a
quick lambda hack will allow functions to be passed which will do the
modification for you.

in particular, here is a scheme example.  common lisp will do the same
with the addition of #'s and funcalls.

(define (change-em set-a set-b)
  (set-a 3) (set-b 5))

(define (look-at-em)
  (let ((a 1) (b 2))
    (change-em (lambda(x) (set! a x)) (lambda(x) (set! b x)))
    (list a b)))



i don't recommend doing this.  if you don't know enough to know a
better way, then you probably shouldn't be doing it in your programs.