lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


> You are probably using an implementation of Lua which adds the restriction to number keys for forcing them to be native integers

The Lua 5.3 and 5.4 behavior is that some floats are converted to
integers when used as table keys, as noted in the manual:

> The indexing of tables follows the definition of raw equality in the language. The expressions a[i] and a[j] denote the same table element if and only if i and j are raw equal (that is, equal without metamethods). In particular, floats with integral values are equal to their respective integers (e.g., 1.0 == 1). To avoid ambiguities, any float with integral value used as a key is converted to its respective integer. For instance, if you write a[2.0] = true, the actual key inserted into the table will be the integer 2.

— Gabriel

On Tue, May 21, 2019 at 4:33 PM Philippe Verdy <verdy_p@wanadoo.fr> wrote:
>
> May be you save 1 byte in source code, but at runtime it's horrible: you create a new table object to use the double value as a key (which is then converted to integer using an unspecified rounding mode...) initialized to a dummy value 0. Then you use the next iterator to extract that key, and the table will be garbage collected. This needlessly stresses the memory allocator and the GC. And it will be very slow compared to math.floor() or math.ceil().
> I'm also not really sure that a table index is necessarily an integer and cannot be a double value.
> The only restriction being that it should not be a NaN value, because it is not comparable. But any other double value can be potentially be used as valid index (including non-integers, infinites, and denormals which are comparable and ordered within the set of doubles minus NaNs). So this pseudo-"technic" is very likely to not be portable/supported.
>
> The official doc currently says "Any value can be used as a key (not just numbers and strings) just make sure it's not nil or NaN (Not a Number)".
> It means that a table like {[0]='A', [0.1]='B'} is valid and contains two distinct pairs because keys 0 and 0.1 are both valid and distinct.
> You are probably using an implementation of Lua which adds the restriction to number keys for forcing them to be native integers (and then allow the backing store to be optimized by not requiring a storage vector for all integers keys, but only for numeric keys that are not part of a sequence) and otherwise store string lkeys separately.
> So, next{[0.1]=2} should return 0.1 (the single key which is not nil and not NaN), and not 0 (some other rounded integer key)...
>
> And your code "x=next{[x]=0}" MUST certainly fail with a runtime exception, if ever x is NaN or nil (invalid key): nothing will be stored in x, and the next iterator will not even be called, or an empty table may be silently created and the next iterator will return nil (no more keys in table) and then x will be assigned a nil value (which will be different "nil" type and no longer a "number" type).
>
>
> Le mar. 21 mai 2019 à 22:14, Egor Skriptunoff <egor.skriptunoff@gmail.com> a écrit :
>>
>> On Tue, May 21, 2019 at 10:55 PM Jonathan Goble <jcgoble3@gmail.com> wrote:
>>>
>>> Took me a few minutes, but I found it:
>>>
>>> x=next{[x]=0}
>>>
>>
>> Correct!
>>