<div dir="ltr"><div dir="ltr">Andres,</div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Sun, Nov 3, 2019 at 6:36 PM Andres Valloud via Cuis-dev <<a href="mailto:cuis-dev@lists.cuis.st" target="_blank">cuis-dev@lists.cuis.st</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Phil,<br>
<br>
> Agreed and I think that's what I latched on to when you first raised the <br>
> issue. This *could* cause some ugly problems down the road. Just <br>
> because it doesn't currently doesn't mean it's not an issue as we might <br>
> not actually see a problem until some useful enhancement down the road <br>
> starts breaking things.<br>
<br>
When I had to debug exception frameworks, the difficulty in verifying <br>
any changes were ok increased with heterogeneous usage, that's for sure.<br>
<br>
Are we writing code to help others help us, or just to please ourselves? <br></blockquote><div><br></div><div>Both... what would be the point of contributing if we didn't like the result ourselves?</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
What are the long term consequences of those two approaches?<br></blockquote><div><br></div><div>That's why I'm arguing for the functionality. Eliminating the functionality that is provided by '^' has short and long term consequences that I think are problematic.</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<br>
> I'm with you as far as '^' usage in an exception handler block goes. I <br>
> think where we have differing opinions is that I'm saying 'yes, let's <br>
> eliminate ^ from exception handler blocks'<br>
<br>
I'd be ok with this, especially if the way the code gets reorganized <br>
makes changing the code further even easier next time. It's also a nice <br>
exercise in awareness to see how horribly difficult it can be to change <br>
or even understand truly heterogeneous code.<br>
<br>
> but at the same time saying <br>
> we should provide an explicit facility to allow for non-local returns <br>
> (i.e. #methodReturn or whatever.) This accomplishes three things:<br>
> <br>
> 1) Avoids potential issues down the road and/or being in the <br>
> uncomfortable position of not being able to implement a feature because <br>
> it will break code that could/should have been legitimately considered <br>
> broken before.<br>
> 2) Provides a mechanism with equivalent functionality that we know will <br>
> *always* be correctly handled by the exception framework.<br>
> 3) Makes the intent explicit (i.e. 'yes, I really did mean to do a <br>
> non-local return in this exception handler')<br>
<br>
I can see that argument for the cases that remain after doing the <br>
cleanup you suggest. Before I agree to this, though, I want to see a <br>
number of examples where there is really no better way to do things <br>
other than with non-local return (regardless of how it is actually <br>
expressed in code).<br></blockquote><div><br></div><div>I can provide code for one example and talk through a couple others:</div><div><br></div><div>1) In OMeta, there are a few places where exception handlers capture rule failures. In one case (<a href="https://github.com/pbella/OMeta-Cuis/commit/4884384de762ca8508b35a8952054f2333b40f26#diff-51b2428bf35caf95ff9fd8b0b88d37d8" target="_blank">https://github.com/pbella/OMeta-Cuis/commit/4884384de762ca8508b35a8952054f2333b40f26#diff-51b2428bf35caf95ff9fd8b0b88d37d8</a> - see line 677 of <a href="http://OMeta2Extensions.pck.st" target="_blank">OMeta2Extensions.pck.st</a>) the non-local return is pointless: it has nothing to do with handling the exception so it makes perfect sense to remove it since we would be returning that value had the exception not occurred. However in <a href="https://github.com/pbella/OMeta-Cuis/blob/4884384de762ca8508b35a8952054f2333b40f26/OMeta2Preload.st#L544" target="_blank">https://github.com/pbella/OMeta-Cuis/blob/4884384de762ca8508b35a8952054f2333b40f26/OMeta2Preload.st#L544</a> and <a href="https://github.com/pbella/OMeta-Cuis/blob/4884384de762ca8508b35a8952054f2333b40f26/OMeta2Preload.st#L606" target="_blank">https://github.com/pbella/OMeta-Cuis/blob/4884384de762ca8508b35a8952054f2333b40f26/OMeta2Preload.st#L606</a> the non-local return is related to handling the exception (i.e. there is nothing more we can do in the current method, return to sender) so it seems to make sense to keep the functionality in the handler. Juan showed that this can be worked around by effectively creating an 'outer' handler around the handler block which performs the non-local return and it does work. But how is this an improvement? The non-local return is still being done, just not from within the exception handler where it really belongs. So now the exception framework doesn't have a full picture of what's going on and the code is a bit less straightforward.</div><div><br></div><div>2) Networking code. Sometimes you will have a method whose job it is to send/receive some data which makes a lot of implicit assumptions which can be invalidated at a moment's notice. Connections (esp. http) have a tendency to just disappear which is to be expected and normal. When that happens, there's often no point in either trying to continue in the current method (you can't do anything to 'fix' it... you no longer have a connection to send to/receive from) or raise an exception up the call stack (the sender can't do anything either): just stop what you were doing and return to the sender whatever the most appropriate return value is. (i.e. the failure should terminate the send/receive operation and the sender can continue but sometimes doesn't need or want to know that it failed)</div><div><br></div><div>For example, I have a periodic task which involves ~10k http requests. A couple hundred of those will fail each run for various reasons: network errors, server down, server errors, page errors etc. There are exception handlers at different levels of connection/request handling that decide if the error is something that needs to be specifically handled / retried or if terminating the request (or perhaps it was terminated on us) and returning some specific value to the sender is the appropriate result. These are almost always non-local returns since we're failing right in the middle of processing a request which is no longer valid.</div><div><br></div><div>3) FFI code and dealing with the 'outside world' more generally. Similar situation as 2: something fails either in an expected place or in an expected way. The current method can't continue but the sender can. Examples: a non-critical log file or database can't be found or has a problem... (maybe) log something to transcript and return from the method in question. A backup file can't be copied to a secondary backup location... we probably aren't connected to the network so ignore it and try again the next time we get called. I have several of these: fatal to the current method but the sender doesn't care.</div><div><br></div><div>The thing all of these examples have in common is that they are all essentially resumable, fatal exceptions... that need to resume somewhere else. Can you rewrite the methods in question to not perform a non-local return in the exception handler? Sure, but what does that get you? Some combination of pretending what happened didn't happen and/or that you resolved the issue when you didn't but instead had the exception handler spill outside the handler block. So now you can say 'See? No non-local returns!' but all you've done is shifted them out of view of the exception framework. So we've gone from bypassing the exception mechanism to lying to it.</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<br>
With these types of things, it's really important to keep options open <br>
and always verify one's assumptions with actual evidence along the way.<br>
<br>
Here's an advantage of your suggestion I didn't see listed above: doing <br>
that would *define* what it means to do a non-local return in an <br>
exception handler block, and thus backfill a hole in section 5.5.2.1.<br></blockquote><div><br></div><div>Yep.</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<br>
> I'm even in favor of saying 'from a best practices standpoint, we <br>
> recommend trying to avoid using #methodReturn' if we wanted to... just <br>
> provide it as an option.<br>
<br>
Yeah, I can see this in general. I'd even phrase it as "from a best <br>
practices standpoint, we recommend avoiding non-local returns in <br>
exception handler blocks, but if you choose to do that then using the <br>
#methodReturn: method provided for that effect helps the maintainers of <br>
the exception framework keep things working as intended because said <br>
method *defines* what it means to do a non-local return in this context".<br></blockquote><div><br></div><div>I'm fine with that.</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<br>
But let's wait until we get there, and especially after we get a feel <br>
for the most difficult cleanup cases. There's no need to put that down <br>
in stone right now.<br></blockquote><div><br></div><div>C'mon folks, the train is at the station and I'm on board. Let's get moving... ;-)</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<br>
> If we did that, then I have no problem in <br>
> flagging '^' in an exception handler as an error by default. (Though we <br>
> would might still want to keep a preference option to not have it be an <br>
> error to help people porting code.) It's taking away '^' without <br>
> providing an alternate way to do it, especially when it's so trivial to <br>
> do and logically consistent with the other functionality provided by the <br>
> framework, that I have a problem with.<br>
<br>
Agreed, one should think about the users of the system.<br>
<br>
> Let's use the Blue Book / ANSI <br>
> as a starting point, not the destination.<br>
<br>
Agreed as well --- no need to get dogmatic over a document that is 20 <br>
years old, we can all think independently.<br>
<br>
So, action items... how about we go after the users of non-local returns <br>
in exception handler blocks and start cleaning them up piece meal? We <br>
could start with that, see what remains after we deal with all the easy <br>
ones, and plan our next move.<br></blockquote><div><br></div><div>I've already started in my code as you've sold me on it being something to avoid when not needed. I've been holding off going beyond that as I don't think we've reached agreement as to the best course of action yet. (i.e. even if you and I agree, I believe Hernan still has a problem with the whole concept)</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<br>
Andres.<br>
-- <br>
Cuis-dev mailing list<br>
<a href="mailto:Cuis-dev@lists.cuis.st" target="_blank">Cuis-dev@lists.cuis.st</a><br>
<a href="https://lists.cuis.st/mailman/listinfo/cuis-dev" rel="noreferrer" target="_blank">https://lists.cuis.st/mailman/listinfo/cuis-dev</a></blockquote><div><br></div><div>Thanks,</div><div>Phil </div></div></div>