This is still way less readable than
local <toclose> file, err = io.open("myfile")
-- ...
However, you can simplify scope() a bit [1], allowing to write
for finally_close in scope() do
local file, err = io.open("myfile", "r")
finally_close( file )
-- ...
end
That is clean enough to not make me miss <toclose>. I can also ignore the fact that the 4th iterator parameter itself is implementated as a <toclose> variable.
But with the last commits we got constant propagation, so I really want <const>. And if we already have annotatations probably <toclose> is worth too.
The annotation system is a considerable addition to the language and it may seem an overkill for a single use case. But it starts to make sense when multiple issues are accounted by it.
Who would endorse the metatables if them were used only for __gc?
pocomane
[1] E.g.:
local function scope()
local obj = {}
local function mark_to_close( o )
obj[1+#obj] = o
end
local function closing()
for i = 1, #obj do
local m = getmetatable( obj[i] )
if m and m.__toclose then
m.__toclose( obj[i] )
end
end
end
local function iter( n, c )
if c == nil then return mark_to_close end
return nil
end
return iter, nil, nil, setmetatable({},{__close=closing})
end