Re: Try/Catch

new topic     » goto parent     » topic index » view thread      » older message » newer message
dcuny said...
Shian_Lee said...

Once you abandon your own obligation and belief, nobody else will take you seriously any more, and won't rely on your product any more.

I'm not sure I see anything about try/catch that can be seen as "abandoning your own obligation."

Euphoria currently has no mechanism for recovering from exceptions.

Yet this is a feature that is expected from modern programming languages, because it is simply unacceptable for programs to shut down on errors and exceptions. Part of this expectation comes from the fact that other modern programming languages do handle exceptions and recover.

Because this is a reasonable expectation, the question is not if it should be done in Euphoria, but how it should be done.

That's the context of introducting try/catch.

So, what's wrong with other approaches?

Consider your with spec example for a moment:

function foo(sequence s) with spec -999 
    return length(s[1..$ - 5]) > 2 
end function 

In order for this to work, you need the value returned from foo to be one of two types: a valid value, or an error indicator.

Guaranteeing that your error value will never appear in range of acceptable values can be tricky, as anyone who's written code where the eof is indicated by -999 and then had that value appear in the data file can attest. blink

And that ignores that what constitutes an error flag will obviously change from routine to routine.

So at a higher level, you'll end up writing code that includes "magic numbers", which is always bad:

result = foo(s) 
if result = -999 then -- magic number 
    -- handle the error 
end if 
 
result = bar(s) 
if result = 99999 then -- another magic number 
    -- handle the error 
end if 
 
result = frotz(s) 
if equal(result,{-99999}) then -- yet another magic value 
    -- handle the error 
end if 

Obviously, you should define these "magic numbers" as constants. But since they can (potentially) change from routine to routine, how do you identify them?

Also, (as has already been mentioned), this solution only works with procedures, which makes it impractical.

But there's another problem: you have to make an error check after every routine call "just in case", or you'll miss an error condition.

And that isn't "simple."

In contrast, try/catch solves the problem much more elegantly. When an error or exception is encountered, it pops the call stack until an error handler is found, and then attempts to recover from the error.

Importantly, if there is no try/catch, the program behaves exactly as it does today. This means that you aren't forced to use this solution, and old code continues to perform as expected.

Compared with other solutions for recovering from exceptions, try/catch is simple, and flexible and easy to learn - all of which are (according to RDS) core features of Euphoria.

But if someone can come up with a solution that better fits these constraints, I'm all ears.

- David

An easy solution to the Magic Number problem is simply to have a dedicated error variable automatically declared for each routine. With each call (func/proc) the var is reset and the 'address' is hidden inside the calling list. The Callee can set the error var by eg, ERR = 1 etc. Upon return the Caller then has the option to check the var (which to it is a private parameter and avoids any 'global' issues).

As for the tedium of having to check the error code each time, we do this already for calls like open() etc.. I think the error treatment of many calls is context dependent (ie, caller driven) and I personally prefer the freedom of being able to specifically choose when to check any error codes.

As for exceptions, I've already suggested defaulting to a safe, though likely incorrect, behaviour and alerting the user or developer in some way. The primary goal in a program should be correctness first and if the program misbehaves it should be stopped to be fixed. If your worried about losing all your precious data crash_routine() could perform an emergency save. Will try/catch (recovering from an exception) guarantee program correctness any more than the above robust error code idea? I strongly doubt it. An indexing exception could be catastrophic to the data and the correct treatment to 'recover' could be as varied as the number of routines that have sequence indexes. There doesn't seem to be any real escape from the proper amount of work needed to deal with these cases.

As for the elegance of try/catch, well, you got me there.

Spock

new topic     » goto parent     » topic index » view thread      » older message » newer message

Search



Quick Links

User menu

Not signed in.

Misc Menu