On Wed, 23 Jul 2008, Allin Cottrell wrote:
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
[...]
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, thanks for the clear analysis of the problem.
Allow me to summarise the whole matter, and please correct any
inaccuracies.
A list, by itself, does not contain anything from the current dataset.
It just holds an array of integers, which correspond to variables.
As of today, when a list is passed to a function, the data available
inside the function (which would otherwise only amount to local objects
and parameters) also includes the "outside" variables referenced by the
var-numbers contained in the list. Moreover, it is currently possible to
modify the list itself (by adding or deleting variable numbers, for
instance); modifying the variables that it references is possible too,
unless "const" is specified. Notice that this is a little weird: "const
list X" does not mean that the list's content is unmodifiable: it means
that the _variables_ it references are.
This liberal attitude has been shown to cause a few problems:
(1) namespace pollution
(2) const stickiness
I will not go into details here (things have been beaten to death already
in the past posts), but (1) implies that a syntactically legal function
may not behave properly in some circumstances, while (2) refers to the
fact that the "const" tag may be lost when calling nested functions, with
imaginably unwanted consequences.
A solution that has slowly emerged is based on imposing restrictions on
the treatment of list members; in the long run:
a) "$i" will contain the orginal ("outside") name of the series; to
access
its contents you will have to use the syntax "listname.$i";
b) the "const" specifier will be always applied (implicitly): you won't be
able to use $i or X.$i on the left-hand side of a genr statement.
This solution will take care of both (1) and (2); its disadvantages are:
i) it won't be possible to modify the series referenced by a list via a
function; the kosher way to achieve the same will be returning a new list
containing the modified data, eg
function cubes(list X)
list ret = null
loop foreach i X
sprintf vname "$i_cubed"
series @vname = (X.$i)^3
ret += @vname
end loop
return list ret
end function
In other words, the form
function cubes(list X)
loop foreach i X
$i = $i^3
end loop
end function
will no longer be legal.
ii) many existing scripts will probably stop working (or worse, they'll
keep running but they'll do something different). Googling for "It used to
work" in the User's list will return bazillions of matches.
In order to ease the transition, here's what we'll do: thanks to the
incredible skill of our commander-in-chief as a C contortionist, _both_
ways will be supported for a limited time period. The new, more stringent,
rules may be toggled on/off via a set command. A special "$" accessor
containing the version number will be provided for the convenience of
script writers.
I know, this was supposed to be a summary, and therefore short. Well, it
isn't. I apologise :-)
Riccardo (Jack) Lucchetti
Dipartimento di Economia
Università Politecnica delle Marche
r.lucchetti(a)univpm.it
http://www.econ.univpm.it/lucchetti