The content of this blog is my personal opinion only. Although I am an employee - currently of Nvidia, in the past of other companies such as Iagination Technologies, MIPS, Intellectual Ventures, Intel, AMD, Motorola, and Gould - I reveal this only so that the reader may account for any possible bias I may have towards my employer's products. The statements I make here in no way represent my employer's position, nor am I authorized to speak on behalf of my employer. In fact, this posting may not even represent my personal opinion, since occasionally I play devil's advocate.

See http://docs.google.com/View?id=dcxddbtr_23cg5thdfj for photo credits.

Thursday, December 21, 2017

WISH: Exception Coalescing Operator/Expressions, like Null Coalescing


I might like exception coalescing expressions and operators, e.g.

result := expression1 ?if-exception expression2 ?if-exception expression3 ... 
result := expression1 ?if-exception(EXCEPTION_TYPE x) x 
along the lines of null-coalescing operators like Perl // or C# ??


I very much like the null coalescing operators, like Perl's //

$a = $b // 'value if b is null/undef';
I suspect that I would also like the Elvis operator ?: if I could get away with using it (i.e. if I felt that my coworkers would not crucify me for using non-standard C), and various safe-traversal operators like ?. ?[] etc.

Today, writing some unit test code, I wanted to do simple exception handling, and I think that I realized that I might like to have an exception coalescing operator, or, more generally, try-catch style exception handling as an expression rather than a statement.

I wanted to do 

result := f(input) or "error" if an exception was thrown
which usually looks like

try {
     result := f(input);
     assert( result == expected );
} catch( ... ) {
     assert( 'according to whether exception is expected or not' );
possibly testing for particular exceptions.

Of course, I (or the test framework) usually have functions like

test_assert_equals( f(input), expected_value )

test_expect_exception( f(input), expected_exception )

f := if_not_exception( f(input), 'exception_value' ).
but that can be quite clumsy.  And, in non-test cases, you may want to chain

f := if(_not_exception( g( if_not_exception( f(input), 'exception_value' )), "exception2")
In general function(args) can be clumsy compared to prefix_fn(args).suffix_fn.suffix_fn2.

In this particular case, I think that I would like an exception coalescing operator

result := expression1 ?if-exception expression2
equivalent to

declare result
try {
     result := expression1;
} catch( ... ) {
     result := expression2;
return result
and chainable

result := expression1 ?if-exception expression2 ?if-exception expression3 ...
If we wanted to specify exactly what exception is caught

result := expression1 ?if-exception(EXCEPTION_TYPE x) x 
(although this raises the possibility of multifix vs infix binary)

Q: what should the operator be?   While I could live with ?if-exception - especially if in my oft-desired XML-based-programming-language-syntax - many folks would prefer something expressible as ASCII.  I would suggest ??, except that C# already uses that for null coalescing equivalent to Perl //.


But if we can't have a nice set of hard to remember symbols, how about traditional try/catch as an expression?

result := try{ expression1 } catch(...)  {expression2 }
This happens a lot - similarity between expressions and statements.  In LISP everything is an expression. Python gets much of its readability by having a stricter boundary between expressions and statements. And debuggability - accidentally making something into an expression when it should be a statement can be hard to find.

Perhaps there should be expressions corresponding to all statements - bit with a minor syntactic indication.

'via Blog this'

No comments: