lua-users home
lua-l archive

Re: Definition of table.insert

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


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

AltStyle によって変換されたページ (->オリジナル) /