Re: RFE: table ctor syntax enhancement for many-to-one mappings
[
Date Prev][
Date Next][
Thread Prev][
Thread Next]
[
Date Index]
[
Thread Index]
- Subject: Re: RFE: table ctor syntax enhancement for many-to-one mappings
- From: Lorenzo Donati <lorenzodonatibz@...>
- Date: 2011年8月22日 01:03:24 +0200
On 19/08/2011 16.25, Tony Finch wrote:
Dirk Laurie<dpl@sun.ac.za> wrote:
A less trivial example of the proposed syntax extension would be:
tbl = { ['a','b','c']=good, [4,5,6]=bad, [7,'8','9']=so_so }
function flatten_keys(template)
local tbl = {}
for keys,val in pairs(template) do
for i,key in ipairs(keys) do
tbl[key] = val
end
end
return kv
end
tbl = flatten_keys{ [{'a','b','c'}] = good,
[{4,5,6}] = bad,
[{7,'8','9'}] = so_so }
Tony.
Unfortunately I found a rather big problem to your approach. It trades
expressiveness for robustness of code. In fact all goes well if the keys
in different groups are unique. Whenever you have duplicate keys, things
go awry (I'll abbreviate flatten_keys with F):
t = F{
[{'a', 'b', 'c'}] = 1,
[{'a'}] = 0,
}
what's the value of t['a'] ?
with my proposal it would have been 0, since the entries would have been
processed in order, and the last assignment to t.a would have been t.a =
0 (table constructor guarantee sequential processing).
But in this case the iteration in F among key groups is done using
pairs, whose iteration order is unspecified, so it may well be that
{'a'} group will be processed before group {'a','b','c'}. In this case
the syntax would be misleading. The problem is serious because the
iteration order may even change adding another group.
One could argue that this idiom is to be used only with disjoint key
groups, but this could lead to brittle code: if someone entered a
duplicated key by mistake, it could lead to very hard to find bugs.
A partial solution would be to track already processed keys:
local function MapNTo1( t )
local map = {}
local already_seen = {}
for keys, value in pairs( t ) do
for _, key in ipairs( keys ) do
if not already_seen[ key ] then
already_seen[ key ] = true
map[ key ] = value
else
error( "key already seen: " .. tostring( key ), 2 )
end
end
end
return map
end
But in a very large map (where my proposal would have been very helpful)
this could help only partially:
t = MapNTo1{ -- this is line N
...
-- 50 lines of data
...
} ---> error signaled at line N
In which line lies actually the culprit?
My proposal had some points after all :-)
-- Lorenzo