[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Another example for syntactically lightweight closures
- From: Mark Hamburg <mhamburg@...>
- Date: Mon, 04 Feb 2008 09:28:45 -0800
Consider the following:
local function _unwind_helper( fn, args, n, success, ... )
if not success then
pcall( fn, unpack( args, 1, n ) )
local msg = ...
error( msg, 0 )
else
fn( unpack( args, 1, n ) )
return ...
end
end
function unwind_protect( fn, ... )
local n = select( '#', ... )
local args = { ... }
return function( ... )
return _unwind_helper( fn, args, n, pcall( ... ) )
end
end
Usage:
local f = io.open( "foo.txt" )
unwind_protect( io.close, f )( function()
print( f:read( "*a" ) )
end )
With syntactic sugar for closure arguments, we get:
unwind_protect( io.close, f ) do
print( f:read( "*a" ) )
end
Admittedly, this is only slightly lighter weight, but it does help.
On the other hand, it behaves unexpectedly if we write:
local f = io.open( "foo.txt" )
unwind_protect( io.close, f ) do
return f:read( "*a" )
end
I think one would end up needing to look at how Modula-3 defined function
returns in terms of exceptions but that still makes the behavior of pcall
"interesting" since one would then need to be prepared for it intercepting a
non-local function return.
Using the above assumed sugar, we could also have written the odder looking:
local f = io.open( "foo.txt" )
unwind_protect do io.close( f ) end dp
print( f:read( "*a" ) )
end
I'm not sure that that helps things much...
Mark