# tables

22 messages
12
Open this post in threaded view
|

## tables

 ```I thought I understodd Lua tables, but obviously not. Would someone explain the rules that cover the following (5.1) behaviour of '#': > a={nil,2,3,4,5,6} > =#a 6 > a={1,2,3,4,5,6} > =#a 6 > a[1]=nil > =#a 6 > a={[2]=2, [3]=3} > =#a 0 > a[1]=1 > =#a 3 > a[1]=nil > =#a 3 David B. ```
Open this post in threaded view
|

## Re: tables

 On 3/5/06, D Burgess <[hidden email]> wrote: I thought I understodd Lua tables, but obviously not.Would someone explain the rules that cover the following(5.1) behaviour  of '#':> a={nil,2,3,4,5,6}> =#a6 What I find interesting is that an explicitly set nil value is not considered a "hole" in the table. According to the documentation that shouldn't be.  A bug? -- // Chris
Open this post in threaded view
|

## Re: tables

 What I find interesting is that an explicitly set nil value is not considered a "hole" in the table. According to the documentation that shouldn't be.  A bug? By the way, I find the documentation wording very confusing: The length of a table `t` is defined to be any integer index `n` such that `t[n]` is not nil and `t[n+1]` is nil; moreover, if `t[1]` is nil, `n` ***may*** be zero. For a regular array, with non-nil values from 1 to a given `n`, its length is exactly that `n`, the index of its last value. If the array has "holes" (that is, nil values between other non-nil values), then `#t` ***may*** be any of the indices that directly precedes a nil value (that is, it ***may*** consider any such nil value as the end of the array). It _might_ consider a nil the end?  Well, does it or does it not?  And if it can change I think that needs to be made clear. -- // Chris
Open this post in threaded view
|

## Re: tables

 ```It would seem that we have the "never assigned nil" and the "assigned nil". David B On 3/6/06, Chris <[hidden email]> wrote: > > > > > > > > > > > What I find interesting is that an explicitly set nil value is not > considered a "hole" in the table. > > > > According to the documentation that shouldn't be. A bug? > > > By the way, I find the documentation wording very confusing: > > The length of a table t is defined to be any integer index n such that t[n] > is not nil and t[n+1] is nil; moreover, if t[1] is nil, n ***may*** be zero. > For a regular array, with non-nil values from 1 to a given n, its length is > exactly that n, the index of its last value. If the array has "holes" (that > is, nil values between other non-nil values), then #t ***may*** be any of > the indices that directly precedes a nil value (that is, it ***may*** > consider any such nil value as the end of the array). > It _might_ consider a nil the end? Well, does it or does it not? And if > it can change I think that needs to be made clear. > > -- > // Chris > ```
Open this post in threaded view
|

## RE: tables

 ```The length operator only guarantees a predictable result in the case of an "array" without holes, like: {1, 2, 3, 4, 5}. If there are any holes at all, then you can't rely on the # operator to give you the result you expect. This is why the manual is a bit confusing; it gives a definition that is always valid, but not really useful except in the special case of an array without holes. So, your experiment with {nil, 2, 3, 4, 5} gives you a valid result (according to the manual's definition) but it isn't a useful value. This is not a bug at all, but an optimization. -----Original Message----- From: [hidden email] on behalf of D Burgess Sent: Sun 3/5/2006 5:05 PM To: Lua list Subject: Re: tables It would seem that we have the "never assigned nil" and the "assigned nil". David B On 3/6/06, Chris <[hidden email]> wrote: > > > > > > > > > > > What I find interesting is that an explicitly set nil value is not > considered a "hole" in the table. > > > > According to the documentation that shouldn't be. A bug? > > > By the way, I find the documentation wording very confusing: > > The length of a table t is defined to be any integer index n such that t[n] > is not nil and t[n+1] is nil; moreover, if t[1] is nil, n ***may*** be zero. > For a regular array, with non-nil values from 1 to a given n, its length is > exactly that n, the index of its last value. If the array has "holes" (that > is, nil values between other non-nil values), then #t ***may*** be any of > the indices that directly precedes a nil value (that is, it ***may*** > consider any such nil value as the end of the array). > It _might_ consider a nil the end? Well, does it or does it not? And if > it can change I think that needs to be made clear. > > -- > // Chris > ```<>
Open this post in threaded view
|

## Re: tables

 ```I think the behaviour is dangerous. > =#{nil,2} 2 > =#{[2]=2} 0 The behaviour changes depending on the syntax of construction. David B On 3/6/06, Dolan, Ryanne Thomas (UMR-Student) <[hidden email]> wrote: > > The length operator only guarantees a predictable result in the case of an "array" without holes, like: {1, 2, 3, 4, 5}. If there are any holes at all, then you can't rely on the # operator to give you the result you expect. This is why the manual is a bit confusing; it gives a definition that is always valid, but not really useful except in the special case of an array without holes. > > So, your experiment with {nil, 2, 3, 4, 5} gives you a valid result (according to the manual's definition) but it isn't a useful value. This is not a bug at all, but an optimization. > ```
Open this post in threaded view
|

## Re: tables

 In reply to this post by Chris-41 ``` ```It _might_ consider a nil the end? Well, does it or does it not? And if it can change I think that needs to be made clear. ``` It might. It depends on some magical implementation stuff. I don't think it can be any clearer. :) --adam ```
Open this post in threaded view
|

## RE: tables

 In reply to this post by D Burgess-4 ```This behaviour is not dangerous; it is expected. What is dangerous is trying to use the result of the length operator on an array with holes. In other words, you should never try #{nil, 2} or #{[2] = 2} in the first place. If you do, you must expect an unpredictable result. Furthermore, you cannot expect #{nil, 2} to always return 2, nor #{[2] = 2} to return 0. As I said earlier, the length operator only gaurantees a predictable result with arrays with no holes, so later versions of the interpretter could have #{nil, 2} return 0 and #{[2] = 2} return 2. According to the definition of the length operator, both 0 and 2 are valid lengths of {nil, 2} and {[2] = 2}. -----Original Message----- From: [hidden email] on behalf of D Burgess Sent: Sun 3/5/2006 5:39 PM To: Lua list Subject: Re: tables I think the behaviour is dangerous. > =#{nil,2} 2 > =#{[2]=2} 0 The behaviour changes depending on the syntax of construction. David B On 3/6/06, Dolan, Ryanne Thomas (UMR-Student) <[hidden email]> wrote: > > The length operator only guarantees a predictable result in the case of an "array" without holes, like: {1, 2, 3, 4, 5}. If there are any holes at all, then you can't rely on the # operator to give you the result you expect. This is why the manual is a bit confusing; it gives a definition that is always valid, but not really useful except in the special case of an array without holes. > > So, your experiment with {nil, 2, 3, 4, 5} gives you a valid result (according to the manual's definition) but it isn't a useful value. This is not a bug at all, but an optimization. > ```<>
Open this post in threaded view
|

## Re: tables

 In reply to this post by D Burgess-4 ```On Sunday 05 March 2006 23:39, D Burgess wrote: > I think the behaviour is dangerous. > > > =#{nil,2} Unexpected, yes, but you are *not allowed* to put nils into an array and expect it to work as an array --- as soon as you do so, you stop being able to reliably use the array operators and have to use the fully-fledged table operators instead. I wonder if it would be possible to have a debug option that could check for this kind of thing? So that, say, tables with an empty hash part and a non-empty array part produced a diagnostic if you tried to write a nil into them? It would make it a little more obvious what was going on. -- +- David Given --McQ-+ | [hidden email] | Uglúk u bagronk sha pushdug Internet-glob bbhosh | ([hidden email]) | skai. +- www.cowlark.com --+ ```Attachment: pgp_zucdWG9vA.pgp Description: PGP signature
Open this post in threaded view
|

## Re: tables

 In reply to this post by Dolan, Ryanne Thomas (UMR-Student) On 3/5/06, Dolan, Ryanne Thomas (UMR-Student) <[hidden email]> wrote: This behaviour is not dangerous; it is expected.  What is dangerous is trying to use the result of the length operator on an array with holes.In other words, you should never try #{nil, 2} or #{[2] = 2} in the first place.  If you do, you must expect an unpredictable result.Furthermore, you cannot expect #{nil, 2} to always return 2, nor #{[2] = 2} to return 0.  As I said earlier, the length operator only gaurantees a predictable result with arrays with no holes, so later versions of the interpretter could have #{nil, 2} return 0 and #{[2] = 2} return 2.  According to the definition of the length operator, both 0 and 2 are valid lengths of {nil, 2} and {[2] = 2}. Can someone define what a "hole" in an array is?  Why can't I have an array with nil values in it?  The current behaviour suggests those are not holes.  However, the documentation gives a vague explaination that says nils *might* be "holes".  But again, judging by the actual behaviour, setting a particular entry in an array to nil is not considered a hole.   I think that's probably a good thing because it allows me to build an array and set some values to nil as a placeholder. However, if a change in implementation could change this behaviour that makes me feel uneasy.  This whole issue makes me realize that Lua really needs an official well defined language specification to be taken seriously. -- // Chris
Open this post in threaded view
|

## Re: tables

 In reply to this post by Dolan, Ryanne Thomas (UMR-Student) ```How about - > a={1,2,3,4,5,6} > a[1]=nil > =#a 6 Surely, one would *expect* # to return the same number as the number of iterations produced by ipairs() ? David B. Ryanne Thomas (UMR-Student) wrote: > In other words, you should never try #{nil, 2} or #{[2] = 2} in the first place. If you do, you must expect an unpredictable result. ```
Open this post in threaded view
|

## Re: tables

 In reply to this post by Chris-41 ```Hallo, On 3/5/06, Chris <[hidden email]> wrote: > > However, if a change in implementation could change this behaviour that > makes me feel uneasy. This whole issue makes me realize that Lua really > needs an official well defined language specification to be taken seriously. > What you must really realize is that you didn't understand the documentation. It could have read "The behaviour of # is undefined if there are holes in the array". But instead it tried to explain what that undefined behaviour would look like, and that confused you. So, to make things clearer, don't use # if you have holes (nils) in the array. Period. -- -alex http://www.ventonegro.org/ ```
Open this post in threaded view
|

## Re: tables

 In reply to this post by Chris-41 ```Chris wrote: ```Can someone define what a "hole" in an array is? ``` nil(s) in an otherwise contiguous run 1..n > Why can't I have an array with nil values in it? you can, but the table length operator on such an array is defined as in the manual. > But again, judging by the actual ```behaviour, setting a particular entry in an array to nil is not considered a hole. ``` No, it's a hole. It simply may or may not affect the length operator, as documented, resulting in a length that you may or may not expect. ```However, if a change in implementation could change this behaviour that makes me feel uneasy. ``` The length operator works as documented, and presumably a change in implementation would also work as documented. You should ask yourself what the expected behaviour would be given an array with holes (count up to the first nil? count up to the last non-nil? something else?). For efficiency Lua's length operator only gives a unambiguous answer in the absence of holes, and is possibly over-wordily documented as such; if you utterly require a specific policy in the presence of holes you can implement it easily enough. > This whole issue makes me realize that Lua really ``````needs an official well defined language specification to be taken seriously. `````` I take Lua pretty seriously! --adam ```
Open this post in threaded view
|

## Re: tables

 In reply to this post by Alex Queiroz On 3/5/06, Alex Queiroz <[hidden email]> wrote:      What you must really realize is that you didn't understand thedocumentation. It could have read "The behaviour of # is undefined ifthere are holes in the array". But instead it tried to explain what that undefined behaviour would look like, and that confused you.     So, to make things clearer, don't use # if you have holes (nils)in the array. Period. No, I understand the documentation.  It's just vague and the implementation is loose. Now, the thing is, I don't really care one way or the other because I don't expect Lua to be standardized like C or something so I just accept it as it is, warts and all.  It works well enough.   I probably shouldn't have gotten involved in this conversation in the first place.  :) -- // Chris
Open this post in threaded view
|

## Re: tables

 ```On Sun, Mar 05, 2006 at 07:29:27PM -0500, Chris wrote: > Now, the thing is, I don't really care one way or the other because I > don't expect Lua to be standardized like C or something so I just accept > it as it is, warts and all. It works well enough. I probably shouldn't > have gotten involved in this conversation in the first place. :) standardized like C? you do not want this! getting numbers ... \$ grep -ic implementation-defined C?9 C89:127 C99:142 \$ grep -ic undefined C?9 C89:108 C99:181 ... so apparently it even got worse? I reckon Lua makes bella figura here. saludos ```
Open this post in threaded view
|

## Re: tables

 In reply to this post by Chris-41 ```Hallo, On 3/5/06, Chris <[hidden email]> wrote: > > Now, the thing is, I don't really care one way or the other because I don't > expect Lua to be standardized like C or something so I just accept it as it > is, warts and all. It works well enough. I probably shouldn't have gotten > involved in this conversation in the first place. :) > Alas, if standards could eliminate warts... -- -alex http://www.ventonegro.org/ ```
Open this post in threaded view
|

## Re: tables

 In reply to this post by Chris-41 ```Chris wrote: > [...] I probably shouldn't have gotten > involved in this conversation in the first place. :) Lots of passionate responses. I initially asked a question. Thanks for the replies. Having reviewed a few historical list mails, I should point out that one of the reasons for # was to provide a syntactically cheap way of table (array) appends, the example provided by Luiz was: t[#t +1] = newvalue So that arrays do not have to be reconstructed and so that we dont have to use (next(t)) == 1 as test for emptiness, it would be convenient (and consistent) if the # operator provided the following behaviour (this is the assertion): "# provides the same number as the number of iterations provided by ipairs". e.g. n=0 ; for i,v in ipairs(t) do n=n+1 end and n = #t "should" provide the same result which means that for i,v in ipairs(t) do and for i = 1, #t do would provide the same number of iterations. This IMHO would provide an improvement in the behaviour of the language and a simplification of the doco. I would not be too fussed if the rule allowed for arrays to be iterated starting at numbers > 1. This argument is about # and ipairs consistency. I note with some interest that the deprecated table.foreachi() provides the consistency that ipairs() does not. David B. ```
Open this post in threaded view
|

## RE: tables

 In reply to this post by D Burgess-4 ```> it > would be convenient (and consistent) if the # operator > provided the following behaviour (this is the assertion): > > "# provides the same number as the number of iterations > provided by ipairs". Convenient maybe, but also more expensive. The current # implementation is O(log(N)) where N is the number of entries in the array part. The rule above would make that O(N) in general. You can use table.maxn to find the highest overall numerical index (ignoring gaps). This is of course also more expensive than applying #. -- Wim This message and attachment(s) are intended solely for the use of the addressee and may contain information that is privileged, confidential or otherwise exempt from disclosure under applicable law. If you are not the intended recipient or agent thereof responsible for delivering this message to the intended recipient, you are hereby notified that any dissemination, distribution, or copying of this communication is strictly prohibited. If you have received this communication in error, please notify the sender immediately by telephone and with a "reply" message. Thank you for your cooperation. ```
Open this post in threaded view
|

## Re[2]: tables

 ```>> it >> would be convenient (and consistent) if the # operator >> provided the following behaviour (this is the assertion): >> >> "# provides the same number as the number of iterations >> provided by ipairs". CW> Convenient maybe, but also more expensive. The current # implementation CW> is O(log(N)) where N is the number of entries in the array part. The plus, it would change the semantics of the # operator such that the expression t[#t+1]==nil would not necessarily be true any more. Gunnar ```
 ```>>> it >>> would be convenient (and consistent) if the # operator >>> provided the following behaviour (this is the assertion): >>> >>> "# provides the same number as the number of iterations >>> provided by ipairs". CW>> Convenient maybe, but also more expensive. The current # implementation CW>> is O(log(N)) where N is the number of entries in the array part. The > plus, it would change the semantics of the # operator such that the > expression t[#t+1]==nil would not necessarily be true any more. That would still be true. (ipairs stops at the first nil value.) -- Wim ```