lua-users home
lua-l archive

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

> Considering an array stops at the first nil integer index is an important part of the lua array concept, and it can't be changed I think. Many code using both hashmap and array concept on same tables would break.

All I am saying is to change how table.remove works. I believe the
change is completely backwards compatible. Here's my proposal again:

function table.remove(t, ind)
 local next
    next = t[ind+1]
    t[ind] = next
    ind = ind+1
  until next==nil

Here is my reasoning for why this proposed version is backwards compatible:

If you were using a table as a mapping, where the keys just so
happened to be integers, you would not use table.remove to remove
entries, you would just do t[ind] = nil (doing otherwise would be a
serious misuse of table.remove!). If you are using a table as both a
hashmap and an array at the same time, well, that code would not be
affected by changing how table.remove works either. There's two cases:

1) The 'map' part uses non-integer keys. This would not be affected by
changing table.remove, since table.remove (both versions) only modify
integer-keyed entries.
2) The 'map' part uses integer keys. There are two sub-cases:
2.1) There is a 'gap' between the array part and the map part: {1,2,3;
[5]='a',[6]='b'}. In this case, the table.remove behavior I propose
will not affect the map part (keys 5 and 6), which is identical to the
behavior now.
2.2) There is no gap between the array part and the map part:
t={1,2,3; [4]='a',[5]='b'}. Again this gives the same behavior as now
-- the current table.remove(t, 3) will shift [4]='a' and [5]='b' down
regardless of whether the program intended for the 'a' and 'b' to be
considered part of the 'map' part of the table. The version I am
proposing will do the same.

If table.setn were still available, then the 2.2 case could return
different results, since one could explicitly say where the array part
ended. But as far as I can tell, there is no longer any way to do that
- table.setn throws an error in 5.1, and setting t.n has no effect and
is ignored by both table.getn and the # operator.

So, unless there is some other hidden way of affecting what is
returned by table.getn that I am not aware of, this change would not
break any existing 5.1 code and has the benefit of making it easier to
work with tables as double-ended queues (see ).

I was using a table in this way and checked to see if table.remove
worked correctly when the table had nils at the front. It did--for the
tests I ran. Then a bizarre bug cropped up in my program and I finally
tracked it down to table.remove not working as expected!