[Cuis-dev] Exception handler blocks with non-local returns

Andres Valloud ten at smallinteger.com
Mon Oct 14 23:48:22 PDT 2019


Phil,

On 10/14/19 22:37, Phil B wrote:
> - Blue Book - Useless... the only thing remotely mentioning exceptions 
> had nothing to do with them.  I don't  see #on:do: referenced anywhere.  
> Wondering if Exception as we know it even existed back then?  I see 
> things like SyntaxError hanging directly off of Object.

IIRC, exceptions were a later invention.

> - ANSI draft - Now we're getting somewhere...
> 
> On p.84 the define #on:do: an mention that 'The result of evaluating the 
> receiver is returned.'  It says nothing about the result of evaluating 
> the exception block.  Something interesting is that on p.84 when talking 
> about #ensure: and #ifCurtailed: they go to the effort of explicitly 
> stating 'the value returned from the evaluation of terminationBlock is 
> discarded' but for whatever reason didn't say anything (the same or 
> different) for #on:do:. >
> On p.92 they define the signaledException protocol which includes 
> #return, #return: etc. and states 'These message are used to explicitly 
> control how execution will continue when it leaves the handler block.'

See section 5.5.2.1, which (if I'm reading it right) says that if a 
handler block does not tell the exception what to do, the behavior is 
equivalent to doing ex return: (the value of the block).

However, the text prefixes that specification by stating "if the block 
answers normally, as if returning from the message #value:".  Ok, so now 
we have an interpretation problem.

Does "answer normally" include non-local return?

1.  Suppose the answer is 'yes'.  Then what does it mean to do

	ex return: anObject

in order to return to a block that is no longer in the stack, because 
presumably the non-local return unwound the receiver of on:do: as well? 
This interpretation does not make sense.

2.  So suppose the answer is 'no'.  Then what happens when the handler 
block has a non-local return?  I do not immediately see what the spec 
says should happen, especially wrt the exception environment --- is that 
even supposed to be reset?  I'd like to believe so, because otherwise 
consider the horrors of a non-local return skipping past exception 
handlers without resetting the exception environment to the closest 
still active handler.

Maybe I missed the text that says what happens?

> Taken together, I'd interpret that as any return value from the handler 
> block is a gray area and implementer's choice.

IIRC, there's non-zero truth in this.  But let's make sure, I'll do some 
more digging tomorrow.

> So as I believe you've 
> stated, the only way to ensure a specific return a value is to send 
> #return (for nil) or #return: (for any other value.)  I find that more 
> than a bit scary since it means that the behavior before the most recent 
> changes was valid.  And so was the behavior after the most recent changes.
> 
> Unless someone can find something else to make be feel better, I'm in 
> full agreement that we do have a problem.

Repeatedly running into this kind of situation is one of the things that 
often makes me wish programs were very explicit about what they want to 
happen.  Because then, if (say) we wanted to change how exceptions work, 
then we can reimplement the messages the application sends so they 
provide the expected behavior in the new world, and everyone's happy.

But if programs do not explicitly say what they mean, now we're in the 
business of guessing.  There's no way to win that, so the steady state 
becomes 'nothing changes anymore'.  Obviously that's unacceptable.

Andres.


More information about the Cuis-dev mailing list