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

Phil B 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:

> Phil,
> 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 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
> here.

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
breaking things.

> Further, section 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.
> Andres.
> --
> Cuis-dev mailing list
> Cuis-dev at lists.cuis.st
> https://lists.cuis.st/mailman/listinfo/cuis-dev

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.cuis.st/mailman/archives/cuis-dev/attachments/20191103/ed972814/attachment.htm>

More information about the Cuis-dev mailing list