lua-users home
lua-l archive

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


> With current Lua syntax, it is possible to write a function
> "const" so that
>   t1={'a','b'}; const"t1"
> does what you want.

It is? You can set newindex to the metatable to _G, but it wont catch
changes to existing keys. Also hacking _G does not allow you to make
immutable locals.

>> t2[#t2+1]='x' would result in creating a NEW table with contains all the old elements plus a new one. The old table remains unchanged; it is immutable.
>
> Should not `t2[anything]` generate "Attempt to assign to an immutable table"?

Matter of taste IMHO. Having automatical copies on changes is fine
when immutable is default, but I would rather not do it in Lua, since
this really would a get a lot of pants in a twist, when the behavior
of the same statement changes depending if mutable or immutable, so
I'd also rather see an Error.

As we like to talk about syntax so much :-) I would suggest the unary
'*' as freeze operator.
Freeze operator: * [expression]
If the expression is a mutable table it returns a copy with the
immutable flag set.
If the expression is an immutable table already it has no effect.
If the expression is any other primitive, it has no effect.

local foo = *bar  -- foo is now an immutabe copy of bar
local foo = *{1, 2, 3, 4}  -- foo is immutable version of 1,2,3,4. foo
itself can still be made to point to something else
lock foo = *{1, 2, 3, 4} -- foo is now immutable and locked, #foo will
always and ever be 4 in that case (unless another local foo overrides
its scope). foo[1] will always and ever be 1.
lock foo = {1,2,3,4} -- foo will always point to this table (saving a
look up in use), but it contents can be changed

In case of local foo = *{1,2, 3, 4} too create a new table with a
change value would look like this:

foo = *copy(t)[5] = 5 -- copy is an obvious simple function.

To return a deeply frozen copy of a data structure (without circles,
for simplicity now) this function would do (also ignoring metatables
for simplicity now)

function deepFreeze(o)
   if type(k) ~= 'table' then return o;
   local c = {};
   for k,v in pairs(o) do
     c[k] = deepFreeze(v);
   end
   return *c;
end