lua-users home
lua-l archive

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




On 2018-07-15 11:43 AM, Pierre Chapuis wrote:
On Sun, Jul 15, 2018, at 16:22, John Belmonte wrote:
My position on Lua's need for some type of scope exit hook is only stronger these days.  It's not just about resource cleanup.  For example, there are some very interesting concurrency and cancellation control structures being developed as Python libraries [2] [3] which would be cumbersome and much less effective in a language lacking the equivalent of Python's "with" statement.

I kind of agree that something like "with" could be useful in Lua. In my opinion one way to do it would be to have a construct which forces garbage collection of the variables created when exiting the block. This way cleanup would be left to the `__gc` metamethod, but it would be deterministic. The advantage would be that it would also work with code that already uses the `__gc` metamethod as a cleanup possibility.

This syntax is probably not right but the idea is:

with
    local my_resource = acquire()
do
    stuff...
end -- resource GC'd here

One place where this could be useful is iterators. In my code base I have iterators that allocate resources that should absolutely be released after iteration, e.g. database transactions. The iterator does it after all items have been iterated, but it does not work if the calling code breaks the loop, so I have to write things like this:

    local _next, _state = some_iterator()
    for v in _next, _state do
        if some_condition then
            _state:clear()
            break
        end
    end

With that construct we let `__gc` clear the state and do this instead:

    with
        local _next, _state = some_iterator()
    do
        for v in _next, _state do
            if some_condition then
                break
            end
        end
    end

There could even be some syntactic sugar for the for loop, e.g.:

    for v with some_iterator() do
        if some_condition then
            break
        end
    end

--
Pierre Chapuis

Or a very simple syntax sugar:

call io.openwith("/dev/null", "w")
  it:write("hello world!")
end

becomes

io.openwith("/dev/null", "w", function(it)
  it:write("hello world!")
end)

Don't use __gc. Don't rely on __gc. Ban __gc. Debug hooks can't see __gc. __gc is a known sandbox exploit. We can't use __gc for things like this.