lua-users home
lua-l archive

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


Hello,

I propose the following Lua 5.1-compatible change to table.remove():

table.remove (t [, pos] [, count])

Removes count elements from t, starting at position pos, shifting down other
elements to close the space, if necessary. Returns the values of the
removed elements. The default values for pos and count are n and 1,
where n is the length of the table, so that a call table.remove(t)
removes the last element of table t.



Unfortunately a similar change can't be applied to table.insert, as
the pos argument is optional and before the inserted value, so
changing the signature to accept more than one element can't be done
unambiguously: if the second parameter is numeric, one can't decide if
it is an insertion position or an element to insert. Maybe this could
be done with a new function table.insert_multiple( t, pos, ...) ?

Rationale:

The current table library isn't convenient to manage FIFOs
efficiently. Given a table containing some elements, I can at the same
time remove one element and return it (with table.remove), but I can't
do the same with more than one element. Therefore, if I have a
function that can return multiple values from a table FIFO, the only
way I can to this is as follows:

function fifo_write( fifo, ...)
 for i in 1, select('#', ...) do -- push all items on the stack just
to count them
   table.insert( fifo, select( i, ...)) -- push all items on the
stack, select returns the remainder after position i, then VM adjusts
that to 1 return value. re-ouch.
 end
end

function fifo_peek( fifo, count)
 return unpack( fifo, 1, count) -- this is easy
end

function fifo_read( fifo, count)
 local out = { unpack( fifo, 1, count)} -- temporary table, ouch
 for i = count, 1, -1 do
    table.remove( fifo, i) -- several removes. re-ouch.
 end
 return unpack( out)
end


Whereas with my proposed changes one could do


function fifo_write( fifo, ...)
 table.insert_multiple( fifo, #fifo, ...) -- current contents are
shifted up only once, no stack abuse.
end


function fifo_peek( fifo, count)
 return unpack( fifo, 1, count) -- this is easy
end


function fifo_read( fifo, count)
 return table.remove( fifo, 1, count) -- remaining elements are
shifted down once. much better.
end


If anyone cares to tell me why this is a stupid idea, I'm all eyes :-).

--
Benoit.