[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: Definition of table.insert
- From: Axel Kittenberger <axkibe@...>
- Date: Mon, 10 Jan 2011 00:04:44 +0100
For what its worth, if you ever going to redesign table I've a
suggestion. Maybe its not smart to insert it in this discussion which
is not read by those who got tired about holes, # and table.*
discussions. But I think its nicer to insert it into such place as
opening yet anoter, if already waiving Robertos request there where
too many proposals with too little implementation.
Proposal a function table.icopy(table, src, dest, n) which replaces
the need for insert and remove.
It copies n integer keys from src to dest. Its inspired by ECMA's
splice, and for those with C background to behave more like memmove()
to defined when src and destination slice overlap.
With this current insert and remove become trivial:
table.insert(table, pos, value)
if value == nil then
table[#table + 1] = pos
return
end
table.icopy(table, pos, pos +1, #table - pos)
table[pos] = value
end
table.remove(table, pos)
table.icopy(table, pos + 1, pos, #table - pos - 1)
table[#table] = nil
end
Wanted to share that, dunno how lua-ish it is. One function that
replaces two functions and yet is more powerful is minimalistic and
thus very lua-ish. It requires anyone to write this two functions as
there is no in lua implemented default library and disregards the
pragmatism for a function with a simpler interface and thus not so
lua-ish.
icopy itself does not use any notion of # and is thus unimpressed by
any holes, an nil key will be copied to dst - src.
You might the function even more powerful by having another argument
as destination table that may be equal to the source table.
On Sun, Jan 9, 2011 at 2:01 PM, Dirk Laurie <dpl@sun.ac.za> wrote:
> 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
>
>
>