[Cuis-dev] Exception handler blocks with non-local returns
pbpublist at gmail.com
Sun Nov 3 06:48:14 PST 2019
On Sat, Nov 2, 2019 at 2:42 PM Andres Valloud via Cuis-dev <
cuis-dev at lists.cuis.st> wrote:
> On 10/14/19 23:48, Andres Valloud via Cuis-dev wrote:
> >> 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.
> The next to last paragraph in section 184.108.40.206 states that evaluating a
> block with a non-local return results in the abnormal-termination of all
> frames (the standard says 'functions') between the block's home context
> and the block's evaluation. This is interesting for the following reason.
> Of course, when one writes something like
> 1 = 1 ifTrue: [^#lalala]
> irrespective of whether ifTrue: is optimized away, the net effect is
> that ifTrue: had actually been sent, evaluating the block would throw
> away the frame for ifTrue: and return from the method or expression
> where [^#lalala] appears. That's ok because everybody knows ifTrue: is
> meant to be used that way. Similar things happen with e.g.
> 1 to: 10 :: do: [:x | x isPrime: [^x]]
> because everybody knows that do: has no side effects and is safe to
> interrupt. You can verify this by looking at the implementation of do:,
> and it is also the case that, typically, implementors of do: know that a
> non-local return may appear in the received block and so nobody writes
> do: to obstruct that usage.
> Asking for the abnormal-termination of exception frames is a different
> thing entirely. I can believe most people can recite the implementation
> of do: from memory, but I would be really surprised if anyone could
> write an exception framework from scratch without spending some serious
> thought. In short, I think there's a huge familiarity gradient in play
Agreed and I think that's what I latched on to when you first raised the
issue. This *could* cause some ugly problems down the road. Just because
it doesn't currently doesn't mean it's not an issue as we might not
actually see a problem until some useful enhancement down the road starts
> Further, section 220.127.116.11 says nothing of what happens if an exception
> handler block has a non-local return, so the consequence might as well
> be undefined (because, literally, it is not defined). (but if I missed
> the spot where it's defined, I'd be happy to see what it says)
> Given these, and from the experience debugging / fixing exception
> frameworks over the years I mentioned earlier, I conclude that using
> non-local returns in exception handler blocks is asking for trouble at
> best, and undefined at worst. So, if I were to be the one writing code,
> I would not use non-local returns in exception handler blocks.
I'm with you as far as '^' usage in an exception handler block goes. I
think where we have differing opinions is that I'm saying 'yes, let's
eliminate ^ from exception handler blocks' but at the same time saying we
should provide an explicit facility to allow for non-local returns (i.e.
#methodReturn or whatever.) This accomplishes three things:
1) Avoids potential issues down the road and/or being in the uncomfortable
position of not being able to implement a feature because it will break
code that could/should have been legitimately considered broken before.
2) Provides a mechanism with equivalent functionality that we know will
*always* be correctly handled by the exception framework.
3) Makes the intent explicit (i.e. 'yes, I really did mean to do a
non-local return in this exception handler')
I'm even in favor of saying 'from a best practices standpoint, we recommend
trying to avoid using #methodReturn' if we wanted to... just provide it as
an option. If we did that, then I have no problem in flagging '^' in an
exception handler as an error by default. (Though we would might still
want to keep a preference option to not have it be an error to help people
porting code.) It's taking away '^' without providing an alternate way to
do it, especially when it's so trivial to do and logically consistent with
the other functionality provided by the framework, that I have a problem
with. Let's use the Blue Book / ANSI as a starting point, not the
> I don't think I have much more to say about this.
> Cuis-dev mailing list
> Cuis-dev at lists.cuis.st
-------------- next part --------------
An HTML attachment was scrubbed...
More information about the Cuis-dev