lua-users home
lua-l archive

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



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.
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.