• Subject: Re: Bug report in length of simple table
• From: Dirk Laurie <dirk.laurie@...>
• Date: Wed, 14 Sep 2016 10:06:00 +0200

```2016-09-14 9:43 GMT+02:00 Dirk Laurie <dirk.laurie@gmail.com>:
> 2016-09-14 8:32 GMT+02:00  <Tomas.Lavicka@tieto.com>:

> 4. If you give Lua an array that is not a sequence, but
> you thought is was, it is a bug, and the bug is not in Lua.
> Preventing or even merely detecting that bug takes O(1)
> would slow Lua up for everybody and is not a serious option.

It should be "takes O(n) time and would slow Lua up".

> I see a new message from you has just come in. Maybe
> you have in the meantime discovered some things for
> yourself that I have explained above. I am hitting Send
> nevertheless since you will also not be the last person to

OK, I see that you have in fact progressed quite a lot.

> But can you also explain to me next behavior?
>> table.unpack{"a",nil,"c"}
> a       nil     c
>> table.unpack{[1]="a",[2]=nil,[3]="c"}
a

In general #t in the presence of holes depends not only on
the set of key-value pairs, but also on an an internal state
of a random number generator that drives the hashing
algorithm and is different for each table and for each time
that you start up Lua.

In your example, there is also a difference in the algorithm
used to construct tha table. You can see it using the bytecode
compiler.

\$ luac -p -l -l -
table.unpack{"a",nil,"c"}

main <stdin:0,0> (9 instructions at 0x25c3b60)
0+ params, 5 slots, 1 upvalue, 0 locals, 4 constants, 0 functions
1    [1]    GETTABUP     0 0 -1    ; _ENV "table"
2    [1]    GETTABLE     0 0 -2    ; "unpack"
3    [1]    NEWTABLE     1 3 0
4    [1]    LOADK        2 -3    ; "a"
6    [1]    LOADK        4 -4    ; "c"
7    [1]    SETLIST      1 3 1    ; 1
8    [1]    CALL         0 2 1
9    [1]    RETURN       0 1
constants (4) for 0x25c3b60:
1    "table"
2    "unpack"
3    "a"
4    "c"
locals (0) for 0x25c3b60:
upvalues (1) for 0x25c3b60:
0    _ENV    1    0

The three elements are loaded as a list.

\$ luac -p -l -l -
table.unpack{[1]="a",[2]=nil,[3]="c"}

main <stdin:0,0> (8 instructions at 0xe6ab60)
0+ params, 2 slots, 1 upvalue, 0 locals, 8 constants, 0 functions
1    [1]    GETTABUP     0 0 -1    ; _ENV "table"
2    [1]    GETTABLE     0 0 -2    ; "unpack"
3    [1]    NEWTABLE     1 0 3
4    [1]    SETTABLE     1 -3 -4    ; 1 "a"
5    [1]    SETTABLE     1 -5 -6    ; 2 nil
6    [1]    SETTABLE     1 -7 -8    ; 3 "c"
7    [1]    CALL         0 2 1
8    [1]    RETURN       0 1
constants (8) for 0xe6ab60:
1    "table"
2    "unpack"
3    1
4    "a"
5    2
6    nil
7    3
8    "c"
locals (0) for 0xe6ab60:
upvalues (1) for 0xe6ab60:
0    _ENV    1    0

The three elements are stored one by one.

```