In my reply to Sven at
http://lists.wfu.edu/pipermail/gretl-devel/2016-January/006469.html
I said that the general intent in current gretl is that "anywhere a
scalar is wanted a 1x1 matrix is also accepted, and vice versa", so
that the distinction between these types shouldn't matter.
In that claim I was thinking about such objects on the right-hand
side of a "genr" expression, and I think the claim is correct in
that context. However, there's a somewhat different issue with
regard to scalars versus matrices on the left-hand side. Dealing
with this has been on my agenda for a while, but in today's git I've
finally tried to resolve it.
Here's the simplest possible example:
<hansl-fragment>
matrix m = {1,2,3,4}
g = m[1:1]
g = m[1:2]
</hansl-fragment>
Internally, if an expression specifies a sub-matrix (e.g. "m[1:1]")
its result is treated as a matrix, even if it's 1x1. However, if a
1x1 result is assigned to a variable of unspecified type, as in the
first "g" line above, it is "cast" to a scalar. Up till now, that
has meant that the second "g" line would fail: g being a scalar at
that point, you can't assign to it a 2-vector.
You could, of course, "fix" this by saying
<hansl-fragment>
matrix m = {1,2,3,4}
matrix g = m[1:1]
g = m[1:2]
</hansl-fragment>
All the same, it seems bad/unintuitive that gretl is refusing to
mutate a somewhat arbitrary assignment of type not called for by the
user.
So in current git, the automatic typing of a 1x1 result as scalar is
treated as provisional and mutable. I give below a more extended
example, showing three contexts in which the issue can show up. I
should explain that LOOPSAVE is an internal flag, signifying that
gretl will save a "compiled" version of any loops encountered when
executing a user-defined function so that they can be re-run more
efficiently when the function is called again. LOOPSAVE has been
around for a while, but turned off because it broke some function
packages. I've now turned it on, because with the new scalar/matrix
code it doesn't break any packages (I think, but more testing needed
before release).
<hansl>
/* Before: error at j=1 on the second call to savetest(),
since the assigned status of v as a scalar is remembered
from one call to the next (but only if LOOPSAVE is on).
Now works even with LOOPSAVE on.
*/
function scalar savetest (matrix *m, scalar k)
printf "savetest: k=%d\n", k
loop j=1..3 -q
printf " j=%d\n", j
v = m[1:k]
endloop
return k
end function
matrix m = {1,2,3,4}
loop i=1..3 -q
x = savetest(&m, i)
endloop
/* Before: error at i=2 since the assigned status of v
as a scalar is remembered from the first iteration.
Now works OK.
*/
loop i=1..3 -q
printf "i=%d\n", i
v = m[1:i]
print v
endloop
/* Before: error on the second line since g gets assigned
scalar status on the first statement. Now works OK.
*/
g = m[1:1]
g = m[1:2]
</hansl>
I should point out that the new code doesn't really override hansl's
strict typing. That is, if you say
<hansl-fragment>
matrix m = {1,2,3,4}
scalar g = m[1:1]
g = m[1:2]
</hansl-fragment>
You will get an "incompatible types" error on the last line, since
you stated that g is supposed to be a scalar. Only the "imputed"
scalar type is taken as mutable, and to matrix only.
Allin