Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Lua: Perfect Clone Function, Why not?

This is a question I have always wondered why it was not possible. Why can't a perfect clone function be made? Doesn't Lua 5.3 include a table.copy function...which I assume handles all problems/cases.

By various clone functions I meant things like this (shallow, deep, recursive, etc)...

function deep (t) -- deep-copy a table
    if type(t) ~= "table" then return t end
    local meta = getmetatable(t)
    local target = {}
    for k, v in pairs(t) do
        if type(v) == "table" then
            target[k] = clone(v)
        else
            target[k] = v
        end
    end
    setmetatable(target, meta)
    return target
end

function shallow (t) -- shallow-copy a table
    if type(t) ~= "table" then return t end
    local meta = getmetatable(t)
    local target = {}
    for k, v in pairs(t) do target[k] = v end
    setmetatable(target, meta)
    return target
end

function copy1(obj)
  if type(obj) ~= 'table' then return obj end
  local res = {}
  for k, v in pairs(obj) do res[copy1(k)] = copy1(v) end
  return res
end


function copy2(obj)
  if type(obj) ~= 'table' then return obj end
  local res = setmetatable({}, getmetatable(obj))
  for k, v in pairs(obj) do res[copy2(k)] = copy2(v) end
  return res
end

function copy3(obj, seen)
  if type(obj) ~= 'table' then return obj end
  if seen and seen[obj] then return seen[obj] end
  local s = seen or {}
  local res = setmetatable({}, getmetatable(obj))
  s[obj] = res
  for k, v in pairs(obj) do res[copy3(k, s)] = copy3(v, s) end
  return res
end

Sources: https://gist.github.com/MihailJP/3931841 and https://gist.github.com/tylerneylon/81333721109155b2d244

Can some explain why a perfect clone or copy function can't be made?

like image 782
G.T.D. Avatar asked Apr 10 '26 23:04

G.T.D.


1 Answers

To expand on @lhf's perfect note. I think this has been discussed on the Lua maillist on several occasions and I'd say there are two reasons for that: (1) what's perfect and reasonable for one case, is overkill for another one; (2) because of metamethods, upvalues, and circular references, it's difficult to cover various cases perfectly. For example, imagine you provide a proxy table using metamethods. Now, after cloning two of the tables share the same proxy table and whatever is stored by one is visible by another one. Is this a "perfect" clone or not?

On a more philosophical, but still relevant note. Perfection is difficult to achieve because of external links that objects have (and clones may need to preserve those; or not). You own a house. Does your perfect clone own the same house in the same way? Do you each now own 50% of the house? How about the third clone? Or you are happily married. How about your clone? Does the spouse need to be cloned as well? Where is the line between perfect and imperfect in this case?

By the time you care about the difference between deep and shallow copies, you can probably write your own function.

like image 98
Paul Kulchenko Avatar answered Apr 15 '26 11:04

Paul Kulchenko



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!