I'd never heard of ContinueUnwind - do any other languages support it?
I have no idea. It gives you somewhat more flexibility, but I'm not sure how useful it would be to *not* continue the original non-local return.
A simplified proposal would be to always complete the original NLR after the protect block finishes executing. I.e. in the following code, foo1 and foo2 are identical to foo except that they print a message.
caller = ( foo: [ ^nil ]. 'caller' print ). "or foo1 or foo2"
foo: blk = ( blk value ). "no protection" foo1: blk = ( blk unwindProtect: [ 'foo1' print ]. 'bar' print ). "bar will never be printed because blk always does a NLR" foo2: blk = ( blk unwindProtect: [ ^ 'foo2' print ] ). "the NLR in the protect block is ignored, 'caller' will not print"
Though less flexible than the first proposal, this solution seems more intuitive and easier to understand. Comments?
What about nested unwind protect blocks? If an outer unwind protect does a continue unwind, do inner protected blocks get executed first? I guess that would make sense, but perhaps not always. What if the inner protected
The protect blocks "belong" to their enclosing scopes, and they are executed just before that scope would return. That is, the non-local return "unwinds" the stack and executes the protect blocks as it goes along.