On Wed, 23 Jul 2008, Riccardo (Jack) Lucchetti wrote:
I'm ok with list contents being modifiable.... If you invoke a
function with a list argument, you must be aware that the series
in that list may come out modified. As Allin said, it's like a
pointer to an array of series and as such is very useful, for
example for mass-transforming a bunch of series.
I must admit I'm having second thoughts about this, based on these
considerations:
* If we think of "mass-transformation" functions on the pattern of
the built-in gretl functions, the series in the input list are not
touched (logs, lags, diff, ldiff and so on). We get back an
output list with transformed versions of the original series, but
the original series are not destroyed. How many user-written
functions are out there, where the member series of an input list
are altered? I suspect zero, though I could be wrong.
* I'm sorry to say that right now, without PROTECT_LISTS, the
mechanism for setting the const-ness of input list-member series
is broken for the case of nested functions (outer script calls
function A, function A calls function B, and so on). I've just
realized this. What happens is this: we have an internal flag
indicating const-ness for each variable. When we enter a function
that marks a list argument as "const", the const flag is set for
all member variables. When we exit a function, the const flag is
unset for such variables. This is fine for a single level of
function execution, but with nested function calls it breaks as
follows:
Script S calls function A with a list argument L, marked as const.
All members of L are marked const. Fine. Then function A calls
function B, passing L as an argument. Function B exits; members
of L are un-marked as const. Execution returns to function A,
which is now free to modify the members of L, contrary to what was
advertised.
To fix this we'd need a more complex data-structure to represent
the const-ness setting of series variables across levels of
function execution, not just a simple bit flag that is either set
or not set.
* The next point: the breakage outlined above cannot occur
(currently) with PROTECT_LISTS defined. The reason is that, as of
now, an expression such as "listname.varname" is not (in C
parlance) a valid "lvalue". That is, you can't _assign to_ an
object named in that way, although you can use it on the
right-hand side of a genr statement OK.
So, what should we fix? If we arrange for listname.varname to be
a valid lvalue (which is feasible), we then have to address the
const-ness issue properly. Alternatively, we continue to disallow
listname.varname as an lvalue, and the const thing solves itself
(with list protection on) in favour of total const-ness, in the
sense that there's no way to modify the member-series of a list
argument to a function: you can't get a handle on such series in a
way that allows you to modify them.
Allin.