lua-users home
lua-l archive

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


2016-07-07 9:26 GMT+02:00 Tim Hill <drtimhill@gmail.com>:
> Let’s face it, the whole issue of #t and sequences and nils
> comes up again and again and again here .. it really is one
> of the least intuitive parts of Lua.

tinsert, tremove and sort only came in with Lua 3.2, when
getn also came in. Tables could have a field 'n' which getn would
return; otherwise it would make a full traversal of all keys of the
table in search of the largest numerical key. 'tinsert' and 'tremove'
updated 'n' if it was present.

At that stage it was intuitive enough, I'd say, and offered almost
exactly what some of us are clamouring for now. Most of us still
have Lua 5.0 somewhere, I expect (e.g. Ubuntu 14.04 offers
the package `lua50`) so maybe we should just shut up and
use that.

Omitting 'n' was clearly an inefficient use of 'getn', and was
replaced in Lua 5.1 by the nondeterministic length operator
(at that stage stated to have the property no longer promised,
that it occurs at a frontier between non-nil and nil) which gives
the right answer if the table is a sequence. Thus the burden of
using the (newly packaged) table library correctly was shifted
to the user. That is where the trouble started.

We've been searching for the proper approach all through 5.1.x,
5.2.x and 5.3.x (for example, having table.insert(tbl,whatever,-5)
throw an error came in at a minor release) and we are not yet
back to having available what all versions from 3.2.x to 5.0.x had,
except by newbie-unfriendly mechanisms like setting
metamethods or monkeypatching the table library.

So I guess we had better keep arguing, so that Lua 6.0, when
it comes, meets universal acclaim.

In that spirit, I offer another suggestion.

1. Make the intuitive Lua 5.0 behaviour (to use the largest numeric
key of tbl as #tbl) the default. No presently documented property of
the # operator is violated.

2. Instead of 'n', which offends some people, use a secret key
which a modified 'next' (and therefore 'pairs') will not show.

3. New table functions:

table.frontier(tbl[,k])  Returns the k-th frontier of tbl, that is,
an integer n>=0 such that t[n+1] is nil but either n=0 or t[n]
is not nil. If k is omitted, any frontier of t may be returned.

table.getlength(tbl)  Returns the value, if any, to be returned
by #tbl when no __len metamethod has been specified.

table.setlength(tbl,n) Sets n as the value to be returned by
#tbl when no __len metamethod has been specified.

The current O(log n) but nondeterministic #t is obtained by

   setmetatable(tbl,table.frontier)

Users sophisticated enough to wield 'setmetatable' can
be expected to be able to comprehend 'table.frontier' too.