lua-users home
lua-l archive

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


On Tue, 12 Jan 2010 12:12:38 +0200, steve donovan <steve.j.donovan@gmail.com> wrote:

On Tue, Jan 12, 2010 at 11:00 AM, Juris Kalnins <juris@mt.lv> wrote:
do ctx.a=1
 do
   local prev_a = ctx.a
   ctx.a = 2
   g(ctx)
   ctx.a = prev_a
 end
end

...
When writing parser or GUI code, there is a lot of such 'ctx' passing and
value saving.
Dynamic scoping makes writing such code very natural.

True, but also less explicit.  It's easier to analyze explicit code,
like above we can see that exceptions will leave the environment
changed, etc.

I agree. Smart syntax -> silly errors.
Problem is when you start to copy and paste such boilerplate code all
over. I doesn't really add any depth, only mud.


It makes life more tricky (by making variable lookup more
complicated), for some convenience.

steve d.

PS. How about doing a _G + metatable + __index trick?  That could work.

I wish it could.
The code I wrote above actually is incorrect, because it
doesn't allow errors.
You need some way to trigger an action when control leaves
scope (on block end, return, break, or error).
If there is an error, "ctx.a = prev_a" will not get
executed. So code becomes something like the untested below:

local prev_a = ctx.a
ctx.a = 2
local ret = {pcall(g, ctx)}
if ret[1] then
  -- do something with updated value of a
end
ctx.a = prev_a
if ret[1] then return table.unpack(ret, 2)
else error(ret[2]) end

(It's equally painful and verbose to try this in C++,
which also is dynamic-scoping-resistant language)