

As the Lua docs state, an array is a table with a sequence of elements from 1..N.
But my question is: is it ok to build the array out of order? For example:
a = { 1, [3]=3 }
a[2]=2
Is "a" an array? Lua *seems* to think it is (#a returns 3), but the Lua docs seems to be a bit vague on this (it seems to be implied by the term "sequence" in the ref manual).
TIA,
Tim


2013/6/9 Tim Hill < [hidden email]>:
> As the Lua docs state, an array is a table with a sequence
> of elements from 1..N.
>
> But my question is: is it ok to build the array out of order?
> For example:
>
> a = { 1, [3]=3 }
> a[2]=2
>
> Is "a" an array?
The actual term is "sequence" but I know what you mean. Yes, it is.
> Lua *seems* to think it is (#a returns 3), but the Lua docs seems
> to be a bit vague on this (it seems to be implied by the term
> "sequence" in the ref manual).
Not vague, but not labouring the point either. Let's say the Manual
is mathematically precise on the subject.
We use the term sequence to denote a table where the set of all
positive numeric keys is equal to {1..n} for some integer n,
which is called the length of the sequence.
Actually, the routines that depend on this property are not confused
by positive numeric keys that can't be taken for integers, but the
above is what it says.


On Sunday, June 9, 2013, Dirk Laurie wrote: 2013/6/9 Tim Hill <<a href="javascript:;" onclick="_e(event, 'cvml', 'drtimhill@gmail.com')">drtimhill@...>:
> As the Lua docs state, an array is a table with a sequence
> of elements from 1..N.
>
> But my question is: is it ok to build the array out of order?
> For example:
>
> a = { 1, [3]=3 }
> a[2]=2
>
> Is "a" an array?
The actual term is "sequence" but I know what you mean. Yes, it is.
> Lua *seems* to think it is (#a returns 3), but the Lua docs seems
> to be a bit vague on this (it seems to be implied by the term
> "sequence" in the ref manual).
Not vague, but not labouring the point either. Let's say the Manual
is mathematically precise on the subject.
We use the term sequence to denote a table where the set of all
positive numeric keys is equal to {1..n} for some integer n,
which is called the length of the sequence.
Actually, the routines that depend on this property are not confused
by positive numeric keys that can't be taken for integers, but the
above is what it says.
I've been confused on a related matter:
I know that in the current implementation, a sequence that also contains hashes will still work as a sequence. That is, in my experience:
T = {"at one", "at two", property = "some value"}
...works in ipairs and with the length operator. Is this behavior that is dependent on the implementation or is it something that is a formal part of Lua?
Andrew


On 10 June 2013 04:10, Andrew Starks < [hidden email]> wrote:
>
>
> On Sunday, June 9, 2013, Dirk Laurie wrote:
>>
>> 2013/6/9 Tim Hill < [hidden email]>:
>> > As the Lua docs state, an array is a table with a sequence
>> > of elements from 1..N.
>> >
>> > But my question is: is it ok to build the array out of order?
>> > For example:
>> >
>> > a = { 1, [3]=3 }
>> > a[2]=2
>> >
>> > Is "a" an array?
>>
>> The actual term is "sequence" but I know what you mean. Yes, it is.
>>
>> > Lua *seems* to think it is (#a returns 3), but the Lua docs seems
>> > to be a bit vague on this (it seems to be implied by the term
>> > "sequence" in the ref manual).
>>
>> Not vague, but not labouring the point either. Let's say the Manual
>> is mathematically precise on the subject.
>>
>> We use the term sequence to denote a table where the set of all
>> positive numeric keys is equal to {1..n} for some integer n,
>> which is called the length of the sequence.
>>
>> Actually, the routines that depend on this property are not confused
>> by positive numeric keys that can't be taken for integers, but the
>> above is what it says.
>
>
> I've been confused on a related matter:
>
> I know that in the current implementation, a sequence that also contains
> hashes will still work as a sequence. That is, in my experience:
>
> T = {"at one", "at two", property = "some value"}
>
> ...works in ipairs and with the length operator. Is this behavior that is
> dependent on the implementation or is it something that is a formal part of
> Lua?
>
> Andrew
Lua 5.1 defines the length of a table to be "any integer index n such
that t[n] is not nil and t[n+1] is nil" [1]. This definition seems to
ignore any noninteger keys.
Lua 5.2 says this about the length of tables without a __len metamethod:
"... the length of a table t is only defined if the table is a
sequence, that is, the set of its positive numeric keys is equal to
{1..n for some integer n. In that case, n is its length.
...
Note, however, that nonnumeric keys do not interfere with whether
a table is a sequence." [2]
Lua 5.1 and 5.2 both describe the behaviour of ipairs (when the table
doesn't have an __ipairs metamethod) as the following:
"Returns three values: an iterator function, the table t, and 0,
so that the construction
for i,v in ipairs(t) do body end
will iterate over the pairs (1,t[1]), (2,t[2]), ..., up to the
first integer key absent from the table." [3][4]
So ipairs also ignores noninteger keys.
I think it's safe to assume that any Lua implementation following the
official manual's definitions of table length and ipairs will ignore
noninteger keys when it's performing arraylike operations on a
table.
[1] http://www.lua.org/manual/5.1/manual.html#2.5.5[2] http://www.lua.org/manual/5.2/manual.html#3.4.6[3] http://www.lua.org/manual/5.1/manual.html#pdfipairs[4] http://www.lua.org/manual/5.2/manual.html#pdfipairs


On Sunday, June 9, 2013, Choonster TheMage wrote: On 10 June 2013 04:10, Andrew Starks <<a href="javascript:;" onclick="_e(event, 'cvml', 'andrew.starks@trms.com')">andrew.starks@...> wrote:
>
>
> On Sunday, June 9, 2013, Dirk Laurie wrote:
>>
>> 2013/6/9 Tim Hill <<a href="javascript:;" onclick="_e(event, 'cvml', 'drtimhill@gmail.com')">drtimhill@...>:
>> > As the Lua docs state, an array is a table with a sequence
>> > of elements from 1..N.
>> >
>> > But my question is: is it ok to build the array out of order?
>> > For example:
>> >
>> > a = { 1, [3]=3 }
>> > a[2]=2
>> >
>> > Is "a" an array?
>>
>> The actual term is "sequence" but I know what you mean. Yes, it is.
>>
>> > Lua *seems* to think it is (#a returns 3), but the Lua docs seems
>> > to be a bit vague on this (it seems to be implied by the term
>> > "sequence" in the ref manual).
>>
>> Not vague, but not labouring the point either. Let's say the Manual
>> is mathematically precise on the subject.
>>
>> We use the term sequence to denote a table where the set of all
>> positive numeric keys is equal to {1..n} for some integer n,
>> which is called the length of the sequence.
>>
>> Actually, the routines that depend on this property are not confused
>> by positive numeric keys that can't be taken for integers, but the
>> above is what it says.
>
>
> I've been confused on a related matter:
>
> I know that in the current implementation, a sequence that also contains
> hashes will still work as a sequence. That is, in my experience:
>
> T = {"at one", "at two", property = "some value"}
>
> ...works in ipairs and with the length operator. Is this behavior that is
> dependent on the implementation or is it something that is a formal part of
> Lua?
>
> Andrew
Lua 5.1 defines the length of a table to be "any integer index n such
that t[n] is not nil and t[n+1] is nil" [1]. This definition seems to
ignore any noninteger keys.
Lua 5.2 says this about the length of tables without a __len metamethod:
"... the length of a table t is only defined if the table is a
sequence, that is, the set of its positive numeric keys is equal to
{1..n for some integer n. In that case, n is its length.
...
Note, however, that nonnumeric keys do not interfere with whether
a table is a sequence." [2]
Lua 5.1 and 5.2 both describe the behaviour of ipairs (when the table
doesn't have an __ipairs metamethod) as the following:
"Returns three values: an iterator function, the table t, and 0,
so that the construction
for i,v in ipairs(t) do body end
will iterate over the pairs (1,t[1]), (2,t[2]), ..., up to the
first integer key absent from the table." [3][4]
So ipairs also ignores noninteger keys.
I think it's safe to assume that any Lua implementation following the
official manual's definitions of table length and ipairs will ignore
noninteger keys when it's performing arraylike operations on a
table.
[1] http://www.lua.org/manual/5.1/manual.html#2.5.5
[2] http://www.lua.org/manual/5.2/manual.html#3.4.6
[3] http://www.lua.org/manual/5.1/manual.html#pdfipairs
[4] http://www.lua.org/manual/5.2/manual.html#pdfipairs
Thanks for that. I've gone ahead and assumed as much, after reading the same passages. I just didn't see this use of tables explicitly called out / endorsed and so I've always wondered a bit.


On 09/06/2013 20.10, Andrew Starks wrote:
> I know that in the current implementation, a sequence that also contains
> hashes will still work as a sequence. That is, in my experience:
>
> T = {"at one", "at two", property = "some value"}
>
> ...works in ipairs and with the length operator. Is this behavior that is
> dependent on the implementation or is it something that is a formal part of
> Lua?
I really hope so; it would break almost all of my code in the other case.
The 5.2 manual says (3.4.6):
[[ Unless a __len metamethod is given, the length of a table t is only
defined if the table is a sequence, that is, the set of its positive
numeric keys is equal to {1..n} for some integer n. In that case,
n is its length." ]]
According to this definition, the presence or absence of nonnumeric
keys should be irrelevant.
(by the way, if I remember correctly, once upon a time (Lua 4?) there
was a magical 'n' field in arrays).

Enrico


Yeah I was kind of assuming this was the definitive answer, which is good because it is what I assumed. TO my mind what this says is that the "sequenceness" comes and goes depending upon the current state of the table:
x = { [1]=1, [3]=3 }  not an array (hole) x[2]=2  x is now an array (1..3) x.foo = "foo"  Still an array, non positive numeric keys are ignored in def x[1] = nil  No longer an array (doesn't start at one)
Tim
Not vague, but not labouring the point either. Let's say the Manual is mathematically precise on the subject.
We use the term sequence to denote a table where the set of all positive numeric keys is equal to {1..n} for some integer n, which is called the length of the sequence.
Actually, the routines that depend on this property are not confused by positive numeric keys that can't be taken for integers, but the above is what it says.


The important caveat here is that #t still returns a value that
satisfies the predicate listed earlier in the thread EVEN IF IT ISN'T
A SEQUENCE. For a nonsequence table, #t doesn't necessarily return
the LOWEST integer such that its predicate holds. This means that "for
i = 1,#t" and "for i,_ in ipairs(t)" can have different results.
/s/ Adam
On Sun, Jun 9, 2013 at 1:26 PM, Tim Hill < [hidden email]> wrote:
> Yeah I was kind of assuming this was the definitive answer, which is good
> because it is what I assumed. TO my mind what this says is that the
> "sequenceness" comes and goes depending upon the current state of the
> table:
>
> x = { [1]=1, [3]=3 }  not an array (hole)
> x[2]=2  x is now an array (1..3)
> x.foo = "foo"  Still an array, non positive numeric keys are ignored in
> def
> x[1] = nil  No longer an array (doesn't start at one)
>
> Tim
>
>
> On Jun 9, 2013, at 7:04 AM, Dirk Laurie < [hidden email]> wrote:
>
> Not vague, but not labouring the point either. Let's say the Manual
> is mathematically precise on the subject.
>
> We use the term sequence to denote a table where the set of all
> positive numeric keys is equal to {1..n} for some integer n,
> which is called the length of the sequence.
>
> Actually, the routines that depend on this property are not confused
> by positive numeric keys that can't be taken for integers, but the
> above is what it says.
>
>


2013/6/10 Coda Highland < [hidden email]>:
> This means that "for
> i = 1,#t" and "for i,_ in ipairs(t)" can have different results.
So supply __ipairs.
With __len available, the safe thing to do is to use it. E.g.
let it return the value of a field `n` in your array, such as
table.unpack so helpfully supplies.
We've come a long way since 4.0, let's say about 400
metres on a standard athletics track. :)


On Sun, Jun 9, 2013 at 8:07 PM, Dirk Laurie < [hidden email]> wrote:
> 2013/6/10 Coda Highland < [hidden email]>:
>
>> This means that "for
>> i = 1,#t" and "for i,_ in ipairs(t)" can have different results.
>
> So supply __ipairs.
>
> With __len available, the safe thing to do is to use it. E.g.
> let it return the value of a field `n` in your array, such as
> table.unpack so helpfully supplies.
>
> We've come a long way since 4.0, let's say about 400
> metres on a standard athletics track. :)
>
Oh, of course, I'm not discounting this, just pointing out an
important note about the semantics, since we were discussing them.
/s/ Adam

