[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: Definition of table.insert
- From: Dirk Laurie <dpl@...>
- Date: Sun, 9 Jan 2011 15:01:48 +0200
On Sat, Jan 08, 2011 at 09:21:05AM +0200, Henning Diedrich wrote:
>
> Just to get it straight: can it ever make sense to insert nil using
> table.insert()?
>
> 'Should' that not rather throw an error, because any table.insert() after
> that could have undefined behavior?
>
> Isn't it pretty much guaranteed you'd never want to do
> |table.insert(t,n,nil)|?
>
> Or is the rationale that you could fill that hole the next second and duly
> have a strict array again?
>
> I tried writing a test loop with inserts and removes on associative arrays
> and could not come up with a prediction for insert (I understood, that's not
> defined). Insert replaces values in associative arrays sometimes, instead of
> moving values up as far as I can see. I can accept it just should not be
> used.
>
> But why would insert be allowed to make the table invalid 'for itself' and
> put it in such a state. After all, it's not allowed to accept a string
> either. So why a nil? That's not a rhethoric question, I am wondering and if
> I have overlooked the decisive message in the list, let me know,
>
We have had many discussions on this list on table functions,
and I think the following points are not in dispute:
1. The insert, remove and sort functions (and in Lua 5.2, the length
operator) are designed to work for what I call annotated lists,
i.e. tables that may or may not contain non-numeric keys, but the
positive integer keys form a block from 1 to n, where n is the
length of the table.
2. They give predictable and intuitively acceptable results when used
in the situation for which they were designed.
3. They do not check whether the table has the required property and
do not return an error message when used outside their design
specification.
4. Their behaviour in such cases, i.e. when used with a table with
holes, or when insert is called with "nil" as the element to be
inserted, is not defined, but can for a particular Lua version
be deduced by making a few experiments.
5. Exception: although the behaviour of the length operator is
undefined for a table with holes, a property that even in that
case it must have, has been written into the reference manual.
6. insert(a,b) does not do the same as insert(a,b,nil). This
behaviour would not be possible for a function of three arguments
written in Lua itself.
In view of point 6, Steve Donovan has made the suggestion (also
not disputed) that it is good programming practice to define 'append'
to mean the same as 'insert', and to use 'append' only in the case
of two arguments, and 'insert' only in the case of three arguments.
The points highly in dispute all concern what the behaviour under
point 4 should be. Roberto and Luiz seem to be unimpressed by these
discussions, so it is merely an intellectual game among those of
us who take part (and actually, if your post did not start "Hi Dirk",
I would not have considered myself to be still among them).
To answer your questions, both answers IMHO, and sure to stir up
the controversy yet again:
1. I agree with you: it never makes sense to insert nil.
The fact that the current implementation allows you to make a hole
that way is a regrettable undocumented feature, caused by a design
flaw in the API.
It would have been less confusing if the three-argument insert
had the value before the key, so that insert(a,b,nil) means
insert(a,b) as it would have done if written in pure Lua. In that
case it would quite obviously be impossible to insert nil.
But it is too late now.
2. It is easy to make a version that does that if you use append the
way Steve suggests.
local oldinsert = table.insert
function table.append(a,b) oldinsert(a,b) end
function table.insert(a,b,c) if c==nil -- etc
No need to change Lua.
Dirk