lua-users home
lua-l archive

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




On 2018-03-17 08:06 AM, Soni "They/Them" L. wrote:


On 2018-03-17 04:21 AM, Philipp Janda wrote:
Am 14.03.2018 um 18:17 schröbte Pierre Chapuis:
On Wed, Mar 14, 2018, at 15:55, Roberto Ierusalimschy wrote:

Every year or so the list has its recurrent discussion about the length operator and holes in sequences. Quite often, this discussion leads some
people to propose that Lua needs an array type, different from tables.

In practice, this is not the reason why people (at least me, but not only)
wish Lua had an array type.

The main reason is that Lua is a dynamic language where you can
inspect the type of values (with type() mostly), but there is no
standard way to know if a table is supposed to be a sequence
or not when you get it. But in the outside world, things are not
tables, they tend to be sequences or map. This causes issues
when we try to interact with it using Lua.

Lua can interact with the outside world just fine. You just can't map Lua tables to outside arrays/maps automatically. That's to be expected, because Lua tables are more powerful that arrays/maps combined, and that's a win for Lua. Any serialization library that pretends this automatic mapping is (always) possible is flawed in its interface. Fortunately, library interfaces can be fixed. I'd suggest passing some form of schema/format into the serialization function (I don't like mutating/annotating my data structures with information that you basically only use for one function call). There's no need to water down Lua's data structures for the sake of communicating to the outside world.

I have this really weird idea now of doing something like this:

table.haskey(t, k)
table.strip(t, k)
table.nullify(t, k)
setmetatable(t, {__null=value})

local key = {}
local value = {}
local t = setmetatable(t, {__null=value})
t[key] = value -- equivalent to table.nullify(t, k), but table.nullify is meant for when you don't have access to __null/the metatable, perhaps because your library code is meant to work with any libs and not a specific null-providing lib.
assert(t[key] == nil)
local l = false
for k,v in pairs(t) do
  assert(k == key)
  assert(v == nil)
  l = true
end
assert(l)
assert(#t == 1)

(__null must be non-nil for it to work, obviously, and you don't wanna replace __null but it'd just deal with it if you did.)

This gets us great (de)serialization compatibility, and the functions can be made to error for tables without __null?

Sure, tables like {1, 2, 3, nil, 4} still have holes, but that's the point - it doesn't break backwards compatibility.

However note that this has some serious caveats compared to undef:

1. No support for ... == undef, for testing if there are any varargs left. (useful for pure-Lua select) 2. No support for explicit LUA_TNONE when calling C functions (converted to nil when calling Lua functions, unless we get default values for args at some point).
3. No support for non-lexical variable scoping.

These 3 features are impossible without something like undef. While we do have select, a lot of assholes make sandboxes without select. I'd love to figure out why they remove select, so if any of them are reading this please tell me, but to me it really makes no sense and we should do our best to put select in the language instead, and by that I mean making it possible to reimplement select in pure-Lua without help from C libraries. And this does absolutely nothing for non-lexical variable scoping.



Philipp





--
Disclaimer: these emails may be made public at any given time, with or without reason. If you don't agree with this, DO NOT REPLY.