lua-users home
lua-l archive

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


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
>
>
>