array functions



Dan Stanger <dan.stanger@ieee.org> writes:

> If I declare the array function h1[k](x):=block(print(x));
> and execute h1[1]([1,2]);
> it prints x, not [1,2] but the function returns [1,2].
> Shouldnt it print [1,2], not x?
> I see this behavior in maxima 5.5, and Macsyma 2.4.
> Can anyone think of a work around for this or explain this behavior?

I notice that Stavros has already answered this, so here are just
some more details:


(C1) foo[k](x):=print(x);
(D1) 			      foo (x) := PRINT(x)
				 k
(C2) foo[1](7);
x 
(D2) 				       7

First, let's look at the cached version of the function array foo.

(C3) :lisp(symbol-plist (mget '$|foo| 'hashar))
(ARRAY #(4 1 1 NIL (((1) (LAMBDA SIMP) ((MLIST) $x) $x)) NIL NIL))

We find that the definition of foo[1] doesn't contain the call to
$PRINT anymore.  Browsing mlisp.lisp, we find a suspect.

(C3) :lisp(trace constlam)

And indeed...

(C3) foo[2](13);

1. Trace: (CONSTLAM '((LAMBDA) ((MLIST) |$x|) (($PRINT) |$x|)))
x 

1. Trace: CONSTLAM ==> ((LAMBDA) ((MLIST) |$x|) |$x|)
(D3) 				      13
(C4) foo[2](13);
(D4) 				      13

Now, CONSTLAM has a funny definition.

(DEFUN CONSTLAM (x &aux (lam x))
 (IF AEXPRP
     `(,(CAR LAM) ,(CADR LAM) ,@(MBINDING ((MPARAMS (CADR LAM)))
					  (MAPCAR #'MEVAL (CDDR LAM))))

     LAM))

So, apparently, the forms which make up the function definition are
MEVALed in Maxima's global environment (which has the side-effect of
printing x) and the results are put together to form the cached
function definition, at least in simple cases like this one.

On the other hand, this seems to imply that function arrays can't be
used to manipulate global bindings. Hmm...

(C5) cnt:0;
(D5) 				       0
(C6) bar[k](x):=(cnt:cnt+x);
(D6) 			   bar (x) := cnt : cnt + x
			      k
(C7) bar[1](1);

1. Trace: (CONSTLAM '((LAMBDA) ((MLIST) |$x|) ((MSETQ) |$cnt| ((MPLUS) |$cnt| |$x|))))
1. Trace: CONSTLAM ==> ((LAMBDA) ((MLIST) |$x|) |$x|)
(D7) 				       1
(C8) cnt;
(D8) 				       x
(C9) bar[1](1);
(D9) 				       1
(C10) cnt;
(D10) 				       x
(C11) 

Indeed.

So is this a bug or should we add some warning to the manual?

Wolfgang