[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: [ANN] Lua 5.4.0 (work1) now available
- From: Sean Conner <sean@...>
- Date: Wed, 14 Mar 2018 15:17:47 -0400
It was thus said that the Great Pierre Chapuis once stated:
> 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.
I had the same issue when writing my CBOR interface [1]. By default, an
empty table becomes an empty map. I can get around this a few ways:
--[[ explicitely call on empty sequence ]]
a = {}
x = cbor.TYPE.ARRAY(a)
--[[ use metatable on sequences ]]
a = setmetatable(
{},
{
__tocbor = function(...)
return cbor.TYPE.ARRAY(...)
end
}
)
x = cbor.encode(a)
--[[ change default behavior of mapping tables ]]
cbor.__ENCODE_MAP.table = function(value,...)
if next(value) == nil then
return cbor.TYPE.ARRAY(value,...)
elseif #value > 0 then
return cbor.TYPE.ARRAY(value,...)
else
return cbor.TYPE.MAP(value,...)
end
end
a = {}
x = cbor.encode(a)
Each has their tradeoffs.
An issue with having a separate array type is how do you know when one is
created? Sure, this:
{ 1 , 2 , 3 , 4 , 5 }
is an array. This:
{ [100] = 1 , [200] = 2 , [300] = 3 , [400] = 4 , [500] = 5 }
results in a map (or associative array). It's obviously NOT an array. But
then this:
{ [1] = 1 , [2] = 2 , [3] = 3 , [4] = 4 , [5] = 5 }
Should that be an array? Or a map? And there are times when I've done
this:
{
alpha = 1 ,
beta = 2 ,
gamma = 3 ,
delta = 4 ,
[1] = alpha,
[2] = beta,
[3] = gamma ,
[4] = delta
}
(usually via programming, but not always). It is useful, and I used such a
construction in my CBOR encoder/decoder:
TAG = setmetatable(
{
--[[ encode a tag of __datetime ]]
_datetime = function(value)
return cbor_c.encode(0xC0,0) .. TYPE.TEXT(value)
end,
--[[ decode a tag of 0 ]]
[0] = function(packet,pos,conv,ref)
local value,npos,ctype = decode(packet,pos,conv,ref)
if ctype == 'TEXT' then
return value,npos,'_datetime'
else
throw(pos,"_datetime: wanted TEXT, got %s",ctype)
end
end,
...
so I *like* the current state of affairs.
-spc
[1] https://github.com/spc476/CBOR