lua-users home
lua-l archive

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


On Mon, Nov 23, 2015 at 3:41 PM, Coda Highland <chighland@gmail.com> wrote:
> On Mon, Nov 23, 2015 at 12:09 PM, Javier Guerra Giraldez
> <javier@guerrag.com> wrote:
>> but the real feature is clean up at block exit.  personally, I find
>> Python-like "with" block nicer than "finally" clauses.
>
> Depends on what you're doing with it. "with" blocks are nicer for
> objects that know how to clean themselves up. "finally" clauses are
> nicer if you need to write ad-hoc code in the cleanup block. Obviously
> it's always possible to write either in terms of the other (and I
> demonstrated this already) but if I had to choose one of the two... I
> slightly favor finally's power-user leanings. (That said, I'd probably
> use "with" if I were writing something for end-user scripting that
> needed reliable cleanup, because for the simple cases it's harder to
> screw up.)

I'd like to point out that Lua doesn't actually need a new compound
block syntax (like Python's "with") because it does real lexical
scoping. Python needs a new control block because the duration of a
local variable lasts for the entire function. So it is necessary for
the language to have a way to express a duration syntactically using
the with statement.

For Lua, we can simply annotate the local variable to indicate its
value should be cleaned up when the local scope ends. Something like
this:

function readall(bar)
   fixed local file = io.open(bar)
   return assert(file:read "a") -- file is closed on error or via return
end

I used a "fixed" keyword because the duration of the local's **value**
is "fixed". This is with consideration that the local may escape the
block as an upvalue to a closure. [If I'm being honest, I couldn't
find a better keyword I liked in the dictionary.] If you change the
local's value to something else, you get what you deserve.

This would execute either the existing __gc metamethod or something
new. It may even be useful to define functions that run when the scope
ends:

function foo()
  for i = 1, 2 do
    fixed local function() print("i = ", i) end
  end --> "i = 1\ni = 2\n"
end

-- 
Patrick Donnelly