lua-users home
lua-l archive

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


On Wed, Oct 24, 2012 at 1:03 AM, spir <denis.spir@gmail.com> wrote:
> On 23/10/2012 21:11, Javier Guerra Giraldez wrote:
>>
>> or private fields for OOP:
>>
>> function new_obj()
>>    local color
>>    return {
>>      radius = 10,
>>      setparams =function (self,in_radius,in_color)
>> self.radius=in_radius, color=in_color end,
>>      draw = function (self) draw_circle (self.radius,color) end
>>    }
>> end
>>
>> and lots more.  In fact, once you're used to handle closures around it
>> becomes the natural way to keep state around, avoiding the "function
>> pointer plus opaque pointer" idiom used in C for callbacks.
>>
>> -- Javier
>
>
> Thank you everyone for replies, things are much clearer.
>
> Skipping back to the example of a 'incrementor' which step happens to be
> variable. copying Javier, maybe a safe and more or less lua-ish (?) way to
> do that with a closure would then be:
>
> do
>    local i = 1
>    inc = function (n) return n+i end
>    set_step = function (j) i = j end
> end
> print (inc(1))
> set_step(3)
> print (inc(1))
>
> We are *explicitely* defining a scope with a local (and private) var, call
> it state, and funcs working on it and with it. It is for me an alternative
> way of creating a kind of object, isn't it?
> What is the difference? Maybe it is more efficient, because the env-scope
> has faster access than a table-scope (has it?). Also, state is here hidden.
> Finally, there is no (object/module/type) prefix. We must no forget to
> 'localise' i, precisely, because without prefix it would be easy to change
> it unintentionally.
> With an ordinary object-like table, we would have to prefix calls to inc,
> and no set_step, instead direct access to i. Good or bad, this is more
> customary in dynamic languages, i guess.
>
> inc = {
>    i = 1 ,
>    next = function (n) return n + inc.i end ,
> }
> print (inc.next(1))
> inc.step = 3
> print (inc.next(1))
>
> My first criterion is about clarity, that the code should so-to-say
> obviously mirror the programmer's intention. A reason why I don't like
> ordinary closures. The scopped closure solution (like the first example
> above) is much better. In Lua, there is no explicit notion and syntax for
> objects, so that in fact using a table is not much clearer about intentions.
> For me, an ordinary object in a language having them explicitely would be
> better on clarity than "scopped closures".
>
> <paren>
> In python, funcs have state, so that one can do the following:
>
> def f(n) :
>    return f.step + n
> f.step = 1
> print (f(1))
>
> f.step = 3
> print (f(1))
>
> (Actually, this implicitely closes on the name 'f'.) A kind of intermediate
> solution; but there can be only one func in the "closure-object".
> What do you think?
> </paren>

What you describe is VERY close to the actual way you can do this in
Lua. Look at the __call metamethod:

f = { step = 1 }
function f:__call(n) -- equivalent to f.__call = function(self, n)
    return self.step + n
end
setmetatable(f,f)

print(f(1)) -- outputs 2
f.step = 3
print(f(1)) -- outputs 4

/s/ Adam