• Subject: Re: pairs(t, skey) and ipairs(t, skey)
• From: Tim Hill <drtimhill@...>
• Date: Thu, 3 Oct 2013 11:24:16 -0700

```On Oct 3, 2013, at 2:18 AM, Dirk Laurie <dirk.laurie@gmail.com> wrote:

> 2013/10/3 Tim Hill <drtimhill@gmail.com>:
>
>
> Assuming that "a table is a sequence" and "a table contains a sequence" mean the
> same thing, the implementation therefore aims to keep track of the sequence-ness
> and the length at the cost of two state values.
>
> So `t[0.5]="half"` would break the sequenceness, but `t[0]=0` would not.
> It's a quirk of the current definition too, but does not carry over to
> spoiling the table library.

Yes, these are quirks as you say, but they are quirks in the original definition, and I was trying to minimize change. And yes, strictly if should always be "table contains a sequence", or, more correctly, "the portion of the table that has numeric keys >= 1".

>
>> [B] At table creation time (constructor):
>> -- Set t.nLen = 0
>> -- Set n.bSeq = true
>> (Thus all new tables have a length of zero and are sequences.)
>>
>> [C] New "table.rawlen()" behavior (in Lua pseudo code):
>>
>> function rawlen(t)
>>        if not t.bSeq then return nil else return t.nLen end
>> end
>>
>> (This takes of care of not returning invalid lengths when not a sequence.)
>>
>> [D] New "table.rawset()" behavior (in Lua pseudo code):
>>
>> function rawest(t, k, v)
>>        if t.bSeq and (type(k) == "number") and (k >= 1) then   -- Is "k" within a sequence?
>>                if not isInteger(k) then                                                        -- Non-integral >= 1, break the sequence
>>                        t.bSeq = false
>>                else
>>                        if v == nil then
>>                                if k < t.nLen then t.bSeq = false end           -- Creating an interior hole
>>                                if k == t.nLen then t.nLen = k - 1              -- Trimming last item off sequence
>>                        else
>>                                if k > t.nLen + 1 then t.bSeq = false end       -- Creating a hole beyond end of sequence
>>                                if k == t.nLen + 1 then t.nLen = k end  -- Extending sequence
>>                        end
>>                end
>>        end
>>        -- (Now do legacy rawest() logic here)
>> end
>
> Now the `t[0.5]` break has been hard-coded. Not sure I like that.

I sort of agree, and I've not looked at the Lua current code to see how it handles this. However, if you look at the current definition, it certainly *implies* some kind of integer test within the low-level table code. Actually, t[0.5] does NOT break it, but t[1.5] would, again trying to follow the existing definition with discusses only sequences that begin at 1.

>
>> This is actually very low-cost code in C .. notice how non-numeric keys bypass it all, and
>> most checks are simple logic tests.
>
> Dirk
>
> PS Note how well-behaved I have been in not giving any references to
> 23 previous threads
> on almost this topic, containing 932 messages, some of which propose
> almost this solution.

Indeed .. which kinda says something about the confusion regarding the current behavior of # imho.

--TIm

```