lua-users home
lua-l archive

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


OK, let me try again, having read the whole thread. Top-posting
intentional, since I am not responding in detail to everything in
the post.

* We every now and then have a real Omar Khayyam discussion on
the length operator, holes in tables and the table library: we hear
great argument between doctor and saint, but evermore come out
by the same door as in we went. It's been a long time since the previous
one, which is probably why everybody is joining in with such gusto.

I find it confusing to call an array a list. Lists are supposed to
have O(1) inserts and removes, and the proposal is not for that.
The present table library is a hotchpotch of list and array functions,
not suited at all for the metatable of an array. We will have an
'array' library, with all functions optimized for the new type even
if some names are the same as functions in the 'table' library.

The features that the proposal seems to demand of an array are:
   1. Numerical indices from 1 to array length only.
   2. Nulls inside do not influence any array function.
   3. Syntactic sugar allowing array literals distinct from table literals.
   4. setmetatable does not work for arrays.
   5. Monopoly of list/array functions by the new array type, to the
extent of destroying many traditional ways of using a table.

* There is no way I can agree to Item 5. It is a political dogma and
I oppose it categorically.

* Item 4 is OK (only one metatable for all arrays, like e.g. strings
and threads), retaining of course the ability to set the metatable
for arrays using the debug library.

* Item 3 is for the bikeshedders to discuss.

* Items 1 and 2 appear tractable, and could be implemented
as an array subtype of a table.
   This subtype would not use the hash part of a table.
   It would have an explicit length field (no algorithm for length).
   Rather than changing the meaning of pairs and ipairs, there
     would have an iterator apairs that simply iterates from 1 to
     the length (available to any indexable type).
   array.concat will do something sensible with nil since we are
     allowing holes.
   There will be no array.insert or array.remove. Inserts and
    removes are to be done with table.move so that the expense
    of the operation is obvious to all instead of being swept under
    the carpet.

2018-01-19 12:26 GMT+02:00 Elias Hogstvedt <eliashogstvedt@gmail.com>:
> Lua was my first language and the language I've been using the most for 10~
> years. I want to point this out becuase I don't want to be the guy who's
> coming from X language that want changes in Lua because it's different from
> his favorite language. I'm not really expecting any change but it's fun to
> think about language design and I'm looking for feedback.
>
>
> I think there’s a need for arrays now, especially if we want to solve var
> args being a second class citizen. table.pack introduces the n field as a
> workaround for nil values in a table but this feels a bit like duct tape
> when we could just have an array type in Lua.
>
> In my experience with teaching other people Lua, a lot of time is spent
> explaining the differences between tables and arrays. There’s confusion
> about the length operator, pairs vs ipairs, performance difference, holes in
> tables, etc. The entire table library also only makes sense on tables that
> are treated as arrays and causes undefined behavior when used on tables.
>
> So to solve this I would simply add an array type to Lua which would help
> distinguish between tables and arrays. To distinguish our new array type
> from arrays in other languages that start from 0 and can only contain a
> certain type of value we can just call it a "list" instead.
>
> Since all the table functions in Lua only work or make sense on tables that
> are treated as lists we simply rename _G.table to _G.list. The list object
> should __index to _G.list so it's possible to do “mylist:insert(2)”
>
> Now that we have no table library we can create one with functions that only
> made sense on tables instead.
>     table.get/setmetatable, table.rawget/set, table.rawequal, table.next,
> table.rawlen, table.pairs ( ? )
>
> The length operator on tables would no longer work unless we set a metatable
> on the table with the length operator.
>
> _G.ipairs would no longer be needed and so using pairs on lists would ensure
> correct order while on tables it would not. We can also put _G.pairs in
> _G.list.pairs to allow the syntax "for i,v in mylist:pairs() do"
>
> The list object would be constructed with the syntax [a,b,c] instead of
> {a,b,c} and can contain any value. However list keys are strictly numbered
> and ordered.
>
> "mylist = table.tolist(tbl)"  -  for converting table to list if the table
> is valid.
> "mylist = []"  -  to create a dynamically sized list.
> "mylist = [1,2,3,4,nil,6]"  -  to create a list that is 6 in length.
>
> Var args become a list object. Because of this I think "..." should be
> replaced with @. Here are some lua examples with the old method on top.
>
>
> mytbl.varargs = table.pack(...)
> ======================
> function foo(@)
>      mytbl.varargs = @
>      print(mytbl.varargs[1])
> end
> foo(42)
> =======================
>>> 42
>
>
> local x,y,z = ...
> ======================
> function foo(@)
>     local x,y,z = @:unpack()
>     print(x,y,z)
> end
> test(1,nil,2)
> =======================
>>> 1 nil 2
>
>
> select(“#, ...”)
> =======================
> function foo(a,b,c,@)
>     print(#@)
> end
> foo(1,2,3,4,5,6,7,8,9)
> =======================
>>> 6
>
>
> for i = 1, select(“#”, ...) do print(i, (select(i, ...))) end
> =======================
> function foo(@)
>     for i,v in @:pairs() do
>         print(i,v)
>     end
> end
> test(1,nil,2)
> =======================
>>> 1 1
>>> 2 nil
>>> 3 3
>
> I believe this would simplify and make the language easier to understand.