lua-users home
lua-l archive

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


Am 01.07.2016 um 07:51 schröbte Dirk Laurie:
2016-07-01 6:09 GMT+02:00 Philipp Janda <siffiejoe@gmx.net>:

Of course the `#` operator (and as a consequence the `table` functions)
should raise an error when applied to a non-array table without `__len` ...

But breaking almost every existing Lua program just because its author
was not clairvoyant would be going too far.

The desired effect can be achieved by one function in the standard library.
That's all.

Why does it have to be in the standard library? You can write reasonable array implementations in Lua right now. Why does no one do it? I think for the following reasons:

1.) The array literal syntax is built-in, convenient, and works good enough (until it doesn't), so everybody uses it by default. 2.) The sequence handling in Lua does not raise an error if you pass non-sequence tables. So even if you decide to use a custom array type in your own code, you can't hand it out, because someone *will* use the `#` operator or a table function on it, and things will silently go wrong.

Arrays without holes is actually a reasonable default choice for arrays in Lua. Most of the time you don't need/want `nil`s in your array, and the presence of a `nil` is actually a bug. The problem is that `#` accepts such an array anyway. This is why I suggested `#` should raise an error for non-array tables (and with the proposed subtype you can check efficiently), and why I like the `.n` tables: you get told right away when you passed an invalid table.


Well, actually two, since the second one is useful for any OOP.

~~~~
table.array(tbl[,n])

Sets or modifies the metatable of tbl so that #t always equals n,
__index points to the table library, and t:type() returns "array".
If n is not supplied, it is calculated from the current tbl so that
#tbl+1 is the first key absent from the table. Returns tbl.

This doesn't solve the problem if `#` and the table functions continue to accept regular plain tables. Anyway, you'll still need to adapt `table.insert()` and `table.remove()` to update the array length.


Philipp