Re: array and make_array



Pedro Fortuny Ayuso <xpfa@nh.netherhall.org.uk> writes:

> A different problem is that the following code does not work. Looks
> not like a bug but an issue (one should use make_array if one wants
> local dynamically sized arrays) but not documented (afaik).

> use_fast_arrays : true;
> trial(a):= block([myvar, i],
>  /*local (i)*/  /* Comment this or not, it's the same */
>  array(i,a),
>  for myvar : 1 thru 7 do i[myvar] : [],
>  i[1])$

> (C2) trial(30);
> 
> 
> Error: |$a| is not of type NUMBER.

The problem is that the arguments of `array' are not automatically evaluated.
Here is the relevant part of the definition (from mlisp.lisp)

(defmspec $array (x)
 (setq x (cdr x))
 (cond #+cl
       ($use_fast_arrays
	  (mset (car x) (apply '$make_array '$any
			       (mapcar #'1+ (cdr x)))))

The form's body is evaluated with x bound to (($array ...) $i $a), so
the mapcar form tries to add 1 to $a, which triggers the error.  (With
use_fast_arrays:false, there are explicit calls to `meval' on $a
beforehand).

In principle there is nothing to prevent you from using
`array(NAME,...)'  with a local variable NAME.  Instead of the
function above one could write a macro like

trial(a)::= buildq([a],block([i],
 array(i,a),
 for myvar : 1 thru 7 do i[myvar] : [],
 i[1]))$

Compiling it (with translate_fast_arrays:true) works, too (tested with
5.9.0pre-cvs/clisp 2.28).

Note that all this works properly only for use_fast_arrays:true, otherwise
i is not local.

Wolfgang

-- 
wjenkner@inode.at