lua-users home
lua-l archive

Another example for syntactically lightweight closures

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


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
 

AltStyle によって変換されたページ (->オリジナル) /