lua-users home
lua-l archive

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


On Tue, Sep 28, 2010 at 01:17, Nilson <nilson.brazil@gmail.com> wrote:
> On Tue, Sep 28, 2010 at 2:29 AM, Juris Kalnins <juris@mt.lv> wrote:
>
>> What exactly are the semantics of the functions that you propose?
> When a value stored inside a field is locked, the value of the field
> cannot be changed, what simulates a constant behavior.
>
>> What is the intended use of such feature?
> Protect constants values from accidental or malicious changes, like in
> any other programming language with constants.
>
>>> myprint = function(...) print('Hi',...) end
>>> _G.print = lkset(_G.print)  -- protects against accidental change
>>> _G.print = myprint
>>>>>>
>>>>>> error: attempt to change a locked value:  function: 004755D8
>>
>> so what exactly gets locked -- value of function 'print' or value
>> at the key 'print' in table _G?
>
> What is locked is the value stored inside _G.print field.
>
>> local a = lkset({}) -- is a locked?
> Yes. The value stored in a cannot be changed.
> So a = nil will fail, but a.test = 1 is ok.
>
>> local b = { k = a } -- is b.k locked?
> No.
>
> For your understanding, I must tell the implementation details - no secrets:
>
> The LKBit are in fact 2 bits that represents:
>  00 - UNLOCKED, 01 - LOCK, 10 - LOCKED, 11 - UNLOCK.
> When you assign a field with a LOCKED value, the patch changes the
> bits to 00 - UNLOCKED before store it. The function lkset() sets the
> bits to 01 - LOCK. When you assign a LOCK value to a field:
> 1) if the field is UNLOCKED, it becomes LOCKED
> 2) if the field is LOCKED, then << 2 options - I will decide later>>
> a) error "change a locked..." - this option is the usual constant behavior.
> b) if the new and old values are equal then ok else fail - this option
> makes lkset idempotent.
>
>> local c, d = {}, {}
>> c.k = {}
>> d.k = c.k
>> c.k = lkset(c.k) -- is d.k locked now?
>
> No. Although both references the same object, each one has its own
> storage area.
> The patch will lock this area.
>
>> c.k.v = 1 -- does this work?
>
> Yes.
>
> --- UNFINISHED IDEA BEGIN ---
> But I was working in a new version of original message adding the function:
>  const(value, optional_deep)  <==> lkset(value, true) plus an optional_deep
> that makes all the elements inside the table (tree?), constant.
>
> So to make c.k a read-only table, you should write:
>  c.k = const(c.k,true)
>
> It is not finish because it is too dangerous.
> If the table c.k references a outer table, like _G, it will damage the
> whole LuaState.
> May be a const(value,deep_level) to control how deep the const will be
> applied...
>  true means total
>  0/false/nil means don't apply inside
>  1 or more is the deep level
> May be testing if any references reachs _G
> .
> Note that you still could add new items inside the table.
> The table itself is not locked. Just the values stored inside when you
> called the const()
> --- UNFINISHED IDEA END ---
>
>> setmetatable(c.k, evil_metatable) -- does this work?
> Yes for now.
>
> --- UNFINISHED IDEA BEGIN ---
> I didn't think about that yet.
> Perhaps a convenience parameter in const that makes  __metatable  = false.
>  const(tab,deep_level,lock_metatable)
> --- UNFINISHED IDEA END ---
>
> -----------------------------------------
> Someone would like to help?
>
> A good knowledge of table implementation in Lua will shorten the work.
> A environment ready to make lots of benchmarks to measure the impact
> on regular Lua code will help too.
>
>
> --
> Nilson
>
>

While disallowing changes of individual table values is an interesting
idea, it doesn't look like this offers a whole lot of advantage over
what we can do with metatables already. The only major advantage I see
is being faster, and this is at the cost of some added complexity.

What you call a constant here isn't the same as what many languages
call a constant. Your idea is to be able to set a read-only bit on
individual variables, allowing it to be set and cleared at any time.
Even if you do:
x = 1
lkset(x, true) --lock forever
The compiler can't guarantee that x will always equal 1 before the
call to lkset, nor that lkset in this context will still be a function
that sets the read-only bit. Also, x might be set to the result of
some complex computation before being made constant, i.e. its value is
determined at runtime even though it's not allowed to change after
that.

In comparison, the idea of "constant" in many languages is like:
const x = 1
i.e. you assign a value at the same time the variable is declared, and
it is never allowed to change at any point during execution, and it's
guaranteed that this statement is creating a constant, and the value
is known at compile-time.
This distinction is important because it allows the compiler to do
things it can't do with a variable whose value or constant-ness isn't
known at compile-time. For example on some platforms it takes fewer
instructions to load a constant value into a register than to read one
from memory, so the compiler might duplicate the value of x each time
it's used.

It would be nice to have constants in Lua, and your proposed feature
is interesting, but they are two different things.

-- 
Sent from my toaster.