lua-users home
lua-l archive

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


On Mon, Jul 6, 2015 at 6:15 AM, Cosmin Apreutesei
<cosmin.apreutesei@gmail.com> wrote:
>> Tuples are a special case of constant values. E.g.
>
>
> Uhm, I don't know what you guys are talking about :)
>
> I'm talking multiple-value indexing, not compile-time const tables. The
> first is useful to me and somewhat inefficient to implement in Lua, the
> second is not useful to me and trivial to implement in Lua.
>
> It looks like we just hit the dichotomy between lib coders and app coders
> that I've been hinting at earlier :)
>

They sort of are a special case of constant values, though -- and
strings are a similar special case. If tuples can be pooled like
strings, then they can have reference equality, which means they can
work as table keys as-is.

This IS actually possible to implement in Lua, and it's not TOO
horribly inefficient (O(n log m) overhead per construction, no
additional overhead for reading and indexing):

local tuple_key = {}
local tuple_nil = {}
local tuple_store = {}
local tuple_mt = {
  __newindex = function(t,k,v) error("attempt to modify tuple") end,
  __len = function(t) return t.n end
}
tuple_mt.__metatable = tuple_mt

function tuple_pack(...)
  return { n = select('#', ...), ... }
end

function tuple(...)
  local args = tuple_pack(...)
  local t = tuple_store
  for i = 1, args.n do
    local k = args[i]
    if k == nil then k = tuple_nil end
    local c = t[k]
    if c then
      t = c
    else
      t[k] = {}
      t = t[k]
    end
  end

  local v = t[tuple_key]
  if not v then
    v = setmetatable(args, tuple_mt)
    t[tuple_key] = v
  end
  return v
end

assert(tuple(1,nil,3) == tuple(1,nil,3))
assert(tuple(1,2,3) ~= tuple(1,nil,3))
assert(#tuple(1,2,3) == 3)
assert(tuple(1,nil,3)[2] == nil)

/s/ Adam