Hacker News new | ask | show | jobs
by zeen 5246 days ago
Well, since we are nitpicking nitpicks, allow me to nitpick your nitpick of a nitpick: Lua closures are also composite data structures. You can get/set their upvalues via the debug API. Behold:

  function create()
    local a,b,c,d,e,f,g,h,i,j;
    return function() print(a,b,c,d,e,f,g,h,i,j); end
  end
  function array_get(f, index)
    local k,v = debug.getupvalue(f, index);
    return v;
  end
  function array_set(f, index, value)
    debug.setupvalue(f, index, value);
  end
  function map_get(f, key)
    for i=1,math.huge do
      local k,v = debug.getupvalue(f, i);
      if k == key then return v; end
      if k == nil then return nil; end
    end
  end
  function map_set(f, key, value)
    for i=1,math.huge do
      local k,v = debug.getupvalue(f, i);
      if k == nil then return; end
      if k == key then
        debug.setupvalue(f, i, value);
        return;
      end
    end
  end
  
  function test()
    local f = create();
    array_set(f, 1, "one")
    assert(array_get(f, 1) == "one");
    map_set(f, "b", "something");
    assert(map_get(f, "b") == "something");
    print("Success!")
  end
  test();
If table creation was disallowed, you could use functions in place of tables. And you could repurpose an existing table as the function type's metatable, allowing syntax like func.x=func[y]

Oh, and coroutines probably also fall under composite data structures technically...

1 comments

Very well played! If I were the nitpick-y type ;) I'd wonder whether use of the debug library is kosher (esp. in production code), but you are definitely correct. Though, actually, this again correlates very closely with C/Scheme -- You can use an offset from a stack frame pointer to access stack variables in a function scope in C; and upvalues are just closed-over variables a la Scheme closures.

Actually, that's another point in Lua's favor. The mechanism Lua uses for managing closed-over variables is WAY more elegant than, for example, Ruby's mechanism...