It seems like what is really wanted is a way to clean up a scope when it closes, so it seems like we should just do that. Create a new block frame, such as "defer ... end" or "exiting ... end". Everything that is in scope at the point where the block begins is in scope throughout the block. However, the contents of the block are not executed inline; rather, once execution reaches the point in the code where the block begins, a deferred-execution guarantee is made for the contained code, which will be executed when the scope immediately containing the exiting ... end block is exited (in newest-guarantee-first order).
Isn't it functionally the same as "try..finally" exception handlers ? i.e. this proposal can only work when there are are errors raised and the code cannot continue normally and must pass by exceptionb handlers
try...finally isn't about exception handling. it interacts with exception handling, to be sure, but the entire point is that it's code that runs whether or not there's an error, or even if there's a return statement.
The exception handler may retry by using a tralining recursive call, but there's no way to return directly at the point where the exception/error was raised, without reconstructing a safe context (by the trailing recursive call: all variables that were in scope when the exception/error was raised are lost, except those passed in the error object constructor; note that to work correctlt this requires that this error object is created first before entering into the "try..."; that object should then contain all the necessary datastructures that may allow the exception/error handler to get significant data and possibly restart the function recursively by a trailing call in a return statement; an exception handler however has no obligation to perform such recursive call, in which case the code will only continue after the "try...finally", whose internal scope is no longer accessible).
I think that "try...finally" (as defined in an extension for C and then ported to C++ in complement of "try...catch") is the way to go with Lua.
While I do like try...finally in terms of expressiveness and robustness (it's way more well-defined than <toclose> in the face of multiple errors) it's also a lot more effort on the programmer's part and doesn't solve the "forgot to release it" issue -- it just makes it easier to make sure it happens. I think <toclose> is a better fit for existing Lua programming paradigms.
/s/ Adam