lua-users home
lua-l archive

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


2018-06-02 3:06 GMT-03:00 Dirk Laurie <dirk.laurie@gmail.com>:
At present a table literal can give you a haystack in which a needle
can't be found. I'm thinking mainly of {...} but to make things clearer
the example is an ordinary table literal.

    x = {nil,nil,nil,1,nil,nil}
    for k in ipairs(x) do print(k) end  -- nothing printed
    for k=1,#x do print(k) end  -- nothing printed

You are forced to use 'pairs' and check for the type of the index.

The now-shelved NIL_IN_TABLE would have solved this, but
we will have to wait for Lua 6.0.

 
NIL_IN_TABLE is good only for 'arrays' types, which is an absolutely
reduction of the current amazing versatility of lua tables.
 
A change that might be possible in a minor release is to make
`x[nil]` mean "the length of the table literal from which `x` was
constructed, if still known".

    for k=1,x[nil] do print(x) end  --> 1 2 3 4 5 6

It remains illegal to assign to x[nil].

The implementation would require one currently unused bit in the
table structure.


My view of this problem:

This is precisely the redefinition (and memorization) of a border, which I claim
is the right way to go for a while.

What's necessary is a way to construct a table such that the border is
defined/memoized as the

biggest non-zero positive integer key assigned

(__newindex), maybe with a 'nil' value, something like a constructor of the type

-- e.g.
t = {@ ... @}     -- @rray semantics!

and that's all. This table will keep the information (e.g. at the registry) about
its border and consequently its rawlen. This is simply a table subtype
that could be checked by (e.g.) a table.type() function if (seldom) necessary.

Thus,
1) 'numeric for' will work as expected for arrays.
2) 'pair()' will iterate only through non-nils values, as expected.
3) 'sequences' also don't change.

The table also remains memory efficient, because only non-nils values are stored.
Moreover,

t[#t+1] = nil

also work as expected for arrays, because #t+1 is the biggest key (border) assigned
(__newindex).

The only problem I can see is the 'reduction' of the border. A simple setborder() function
can be used (e.g.)

table.setborder(t,#t-1)

but I think this will be rarely needed for real-world 'array' purposes (shrinks arrays? who? why?)

I think that this solves the problems of Roberto concerning the semantics of an array construction
exposed in an early message to this list, at a minimum cost that also keeps the compatibility
with the current versions of lua. The implementation seems also to be straight.

that makes sense?

Thanks,
Rodrigo Azevedo Moreira da Silva