Question about arrays...

classic Classic list List threaded Threaded
11 messages Options
Reply | Threaded
Open this post in threaded view
|

Question about arrays...

Tim Hill
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


Reply | Threaded
Open this post in threaded view
|

Re: Question about arrays...

Dirk Laurie-2
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.

Reply | Threaded
Open this post in threaded view
|

Re: Question about arrays...

Andrew Starks


On Sunday, June 9, 2013, Dirk Laurie wrote:
2013/6/9 Tim Hill <<a href="javascript:;" onclick="_e(event, &#39;cvml&#39;, &#39;drtimhill@gmail.com&#39;)">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
Reply | Threaded
Open this post in threaded view
|

Re: Question about arrays...

Choonster TheMage
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 non-integer 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 non-numeric 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 non-integer 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
non-integer keys when it's performing array-like 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#pdf-ipairs
[4] http://www.lua.org/manual/5.2/manual.html#pdf-ipairs

Reply | Threaded
Open this post in threaded view
|

Re: Question about arrays...

Andrew Starks


On Sunday, June 9, 2013, Choonster TheMage wrote:
On 10 June 2013 04:10, Andrew Starks <<a href="javascript:;" onclick="_e(event, &#39;cvml&#39;, &#39;andrew.starks@trms.com&#39;)">andrew.starks@...> wrote:
>
>
> On Sunday, June 9, 2013, Dirk Laurie wrote:
>>
>> 2013/6/9 Tim Hill <<a href="javascript:;" onclick="_e(event, &#39;cvml&#39;, &#39;drtimhill@gmail.com&#39;)">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 non-integer 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 non-numeric 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 non-integer 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
non-integer keys when it's performing array-like 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#pdf-ipairs
[4] http://www.lua.org/manual/5.2/manual.html#pdf-ipairs

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.  
Reply | Threaded
Open this post in threaded view
|

Re: Question about arrays...

Enrico Colombini
In reply to this post by Andrew Starks
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 non-numeric
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

Reply | Threaded
Open this post in threaded view
|

Re: Question about arrays...

Petite Abeille

On Jun 9, 2013, at 9:12 PM, Enrico Colombini <[hidden email]> wrote:

> (by the way, if I remember correctly, once upon a time (Lua 4?) there was a magical 'n' field in arrays).

Yeah, looks like 'n' has even made a sneaky comeback in 5.2... :D

http://www.lua.org/manual/5.2/manual.html#pdf-table.pack


Reply | Threaded
Open this post in threaded view
|

Re: Question about arrays...

Tim Hill
In reply to this post by Dirk Laurie-2
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 "sequence-ness" 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.

Reply | Threaded
Open this post in threaded view
|

Re: Question about arrays...

Coda Highland
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 non-sequence 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
> "sequence-ness" 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.
>
>

Reply | Threaded
Open this post in threaded view
|

Re: Question about arrays...

Dirk Laurie-2
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. :-)

Reply | Threaded
Open this post in threaded view
|

Re: Question about arrays...

Coda Highland
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