Fix for $matrix (Was: "matrix([matrix([" returned with mat_function (Was: Re: Symbolic matrix power))



Loading the following Lisp code into Maxima fixes the mat_function problem
caused by apply(matrix,...) incorrectly evaluating its arguments twice. I
have not run the test suite etc. however:


(remprop '$matrix 'mfexpr*)
(defun $matrix (&rest rows)
  (dolist (row rows)
    (if (not ($listp row)) (merror (intl:gettext "matrix: row must be a
list; found: ~M") row)))
  (matcheck rows)
  (cons '($matrix) rows))

To load into Maxima, cut and paste that code into a file and load the file
with loadfile("<<full pathname>>").

For those who are interested in the history....  The old version of
$matrix is written as a defmspec (i.e., an
FEXPR<https://en.wikipedia.org/wiki/Fexpr>;),
a function which is called without evaluating its arguments. This was done
because early versions of Maclisp (before 1974) did not have any other way
of passing a variable number of arguments. There are other gratuitous
defmspec's in Maxima which should probably be rewritten at some point --
$map / $matrixmap /etc.

              -s


On Mon, Oct 28, 2013 at 3:15 PM, Stavros Macrakis <macrakis at alum.mit.edu>wrote:

> It is true that lexical scope rules (or changing the variable name) would
> fix this.
>
> But that only matters if an object is being *evaluated* where it
> shouldn't be. And sure enough, applying the 'matrix' function incorrectly
> re-evaluates its arguments. Here is a simple example:
>
>       q: '[[x]]$
>       x: 3$
>       apply('matrix,q) => matrix([3])     !!!!  should be matrix([x])
>
> This extra evaluation is a bug in 'apply'.
>
>             -s
>
>
>
> On Mon, Oct 28, 2013 at 2:25 PM, Robert Dodier <robert.dodier at gmail.com>wrote:
>
>> > On 10/25/2013 08:26 PM, andre maute wrote:
>>
>> >> (%i2) A : matrix([a,b],[c,d]);
>> >>
>> >> (%o2) matrix([a,b],[c,d])
>> >> (%i3) load("diag");
>> >>
>> >> (%o3)
>> "/home/user/opt/maxima/share/maxima/5.30.0/share/contrib/diag.mac"
>> >> (%i4) integer_pow(x) := block ([k], declare (k, integer), x^k);
>> >>
>> >> (%o4) integer_pow(x):=block([k],declare(k,integer),x^k)
>> >> (%i5) mat_function (integer_pow, A);
>> >>
>> >> (%o5) matrix([matrix([(sqrt(d^2-2*a*d+4*b*c+a^2)-d-a)^k* ...
>>
>> This is due to Maxima's dynamic binding policy -- there is a local
>> variable in diag_mode_matrix named 'a' which is bound to the value of
>> the user variable 'A'. Try it again w/ A : matrix([b, c], [d, e]) --
>> I think you'll get a different result.
>>
>> This particular bug could be fixed by changing 'a' to 'a%' or something
>> to reduce the chance of a name collision, but it doesn't seem worth the
>> trouble -- every local variable really needs the same treatment, and
>> anyway the problem will reappear if someone uses an "unlikely" name.
>> The only way to really fix it is to make local variables lexical instead
>> of dynamic -- I'm in favor of that, for the record.
>>
>> best
>>
>> Robert Dodier
>>
>> _______________________________________________
>> Maxima mailing list
>> Maxima at math.utexas.edu
>> http://www.math.utexas.edu/mailman/listinfo/maxima
>>
>
>