lua-users home
lua-l archive

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



> On Jun 26, 2018, at 6:00 AM, Dirk Laurie <dirk.laurie@gmail.com> wrote:
> 
> 
> That internal state was set to the size of the table as initially created,
> and automatically updated whenever one used table.insert  or
> table.remove. It was not updated by assigning a value to tbl[n+1]
> or by assigning nil to tbl[n].
> 
> Unfortunately, the initial value was not taken from the length of the
> table constructor. Nils at the end of the table were elided.
> 
> But that small change, of setting the internal state to the actual size
> of the constructor, would be all that is necessary to solve all three
> parts of the first of the stated problems, without breaking either
> of the two characteristic properties of Lua which have persisted from
> Lua 1.0 right through to Lua 5.4 work2:
> 
> * "Semantically, there is no difference between a field not present
> in a table or a field with value nil."
> 
> * "Tables are the sole data structuring mechanism in Lua".
> 
> [1] Quoted from Roberto's post
> http://lua-users.org/lists/lua-l/2018-03/msg00239.html
> 
> [2] For which purpose table.insert(t,x) and table.remove(t) are
> specifically designed.
> 

This has always been my feeling .. that there is a semantic difference between a “sequence” in which the length is dynamically computed (and is the root cause of all those long long threads) and an “array” (call it what you want) that has a *declared* size very much like the setn/getn model. None of the suggestions to date seem to address this difference completely (including mine), and to be honest I’m not very keen on the “undef” suggestion for 5.4 either .. which (Roberto will shoot me for saying this) still sounds like the all-hated “value that isnt a value”.

I think the only way out of this mess is to leave sequences, the # operator and ipairs() etc alone. They are what they are, and should stay unchanged to avoid breaking existing code. Then make a couple of additions (not changes) to the language/library:

— Add an internal “array length” value to each table (very much like the old getn/setn). And no, in most cases this will NOT add memory overhead given the granularity of most help allocators these days.

— Alter the language so that table constructors set this new array length, correctly handling cases such as {…} with nils (that is, including them), so the length of {nil, nil} is 2. There is a slight edge case here with functions that return multiple values, “{foo()}", but I see this as analogous to {…}.

— Add a new “array” library that has getn/setn as well as equivalents of insert/append/delete etc that respect the array length. Depending on mood, “apairs()” could be added as well, though I suspect this would be controversial.

Far from ideal, but at least it doesnt break anything. Of course, it bloats the library up, but this is easily addressed using a #define to exclude it.


—Tim