digitalmars.D - TryElseExpression DIP
- pineapple (44/44) Sep 05 2016 I was writing some code and realized D doesn't have an equivalent
- ag0aep6g (6/31) Sep 05 2016 Can you point out how this is different from (and better than)
- pineapple (15/29) Sep 05 2016 In this case, the catch block will catch both errors from
- Jacob Carlborg (4/6) Sep 05 2016 Then move it to after the "finally" block.
- arturg (10/46) Sep 05 2016 hm, isn't this similar/same as the python version?
I was writing some code and realized D doesn't have an equivalent to Python's `else` for error handling, and I think we should change that https://github.com/dlang/DIPs/pull/43/files In Python, the try/catch/finally syntax is augmented with an additional clause, termed else. It is a fantastically useful addition to the conventional syntax. It works like this: try: do_something() except Exception as e: raised else: finally: Imitating this functionality in D, try{ do_a_thing(); }catch(Exception exception){ handle_error(); }else{ depends_on_success_of_thing(); }finally{ do_this_always(); } Would be equivalent to bool success = false; try{ do_a_thing(); success = true; }catch(Exception exception){ handle_error(); }finally{ try{ if(success){ depends_on_success_of_thing(); } }finally{ do_this_always(); } }
Sep 05 2016
On 09/05/2016 08:07 PM, pineapple wrote:
try{
do_a_thing();
}catch(Exception exception){
handle_error();
}else{
depends_on_success_of_thing();
}finally{
do_this_always();
}
Would be equivalent to
bool success = false;
try{
do_a_thing();
success = true;
}catch(Exception exception){
handle_error();
}finally{
try{
if(success){
depends_on_success_of_thing();
}
}finally{
do_this_always();
}
}
Can you point out how this is different from (and better than)
try { do_a_thing(); depends_on_success_of_thing(); }
catch (...) { ... }
finally { ... }
?
Sep 05 2016
On Monday, 5 September 2016 at 18:27:44 UTC, ag0aep6g wrote:Can you point out how this is different from (and better than) try { do_a_thing(); depends_on_success_of_thing(); } catch (...) { ... } finally { ... } ?On Monday, 5 September 2016 at 18:27:52 UTC, arturg wrote:hm, isn't this similar/same as the python version? try{ doSomething(); scope(success) "if no Exception thrown".writeln; } catch(Exception e) { ... }In this case, the catch block will catch both errors from do_a_thing and depends_on_success_of_thing. The places where this sort of pattern is most useful are where you don't want to handle errors in depends_on_success_of_thing at all, because to have thrown an error is very unexpected behavior. Granted scenarios like that are uncommon, but the most important reason for using the separate `else` scope is to help reduce programmer error because they forgot that the error handling in the catch block will break something when it was entered because depends_on_success_of_thing failed. There's also the matter of readability and cleanliness. It is (in my opinion, at least) an intuitive and concise way to handle a not-uncommon case.
Sep 05 2016
On 2016-09-05 20:57, pineapple wrote:In this case, the catch block will catch both errors from do_a_thing and depends_on_success_of_thing.Then move it to after the "finally" block. -- /Jacob Carlborg
Sep 05 2016
On Monday, 5 September 2016 at 19:12:02 UTC, Jacob Carlborg wrote:On 2016-09-05 20:57, pineapple wrote:It would actually have to be inside the "finally" block to reproduce the exact behavior. I included an analog in the original post - I'm not saying that this behavior can't be achieved now, but that this is a concise and more readable pattern which, when utilized, makes it more difficult to accidentally write error-prone code. Which is easier to read and to write? Which is more maintainable? Which is less prone to programmer errors? This? bool success = false; try{ do_a_thing(); success = true; }catch(Exception exception){ handle_error(); }finally{ try{ if(success){ depends_on_success_of_thing(); } }finally{ do_this_always(); } } Or this? try{ do_a_thing(); }catch(Exception exception){ handle_error(); }else{ depends_on_success_of_thing(); }finally{ do_this_always(); } This? try{ do_a_thing(); }else{ depends_on_success_of_thing(); } Or this? bool success = false; try{ do_a_thing(); success = true; }finally{ if(success){ depends_on_success_of_thing(); } }In this case, the catch block will catch both errors from do_a_thing and depends_on_success_of_thing.Then move it to after the "finally" block.
Sep 05 2016
On Monday, 5 September 2016 at 20:04:43 UTC, pineapple wrote:On Monday, 5 September 2016 at 19:12:02 UTC, Jacob Carlborg wrote: [...]There's probably also a FP approach: function TryElse( alias TryStatements, alias ElseStatements)(){} function TryCatchElseFinally( alias TryStatements, alias ElseStatements, alias CatchStatements, alias ElseStatements, E : Exception = Exception)(){} etc. You pass delegate literals: °°°°°°°°°°°°°°°°°°°°° void TryElse(alias TryStatements, alias ElseStatements)() { bool doElses = true; try TryStatements(); catch(Throwable){} ElseStatements(); } void main() { int i; import std.conv: to; TryElse!( {i = to!int("0.42");}, {i = -1;} ); } °°°°°°°°°°°°°°°°°°°°° With optional sugar to name each statements group: °°°°°°°°°°°°°°°°°°°°° template Statements(alias T) { alias Statements = T; } alias Try = Statements; alias Else = Statements; void main() { TryElse!( Try!({}), Else!({}) ); } °°°°°°°°°°°°°°°°°°°°°On 2016-09-05 20:57, pineapple wrote:Which is easier to read and to write? Which is more maintainable? Which is less prone to programmer errors? This? [...] This? try{ do_a_thing(); }else{ depends_on_success_of_thing(); } Or this? bool success = false; try{ do_a_thing(); success = true; }finally{ if(success){ depends_on_success_of_thing(); } }
Sep 05 2016
On Monday, 5 September 2016 at 18:07:52 UTC, pineapple wrote:
It works like this:
try:
do_something()
except Exception as e:
raised
else:
finally:
Imitating this functionality in D,
try{
do_a_thing();
}catch(Exception exception){
handle_error();
}else{
depends_on_success_of_thing();
}finally{
do_this_always();
}
Would be equivalent to
bool success = false;
try{
do_a_thing();
success = true;
}catch(Exception exception){
handle_error();
}finally{
try{
if(success){
depends_on_success_of_thing();
}
}finally{
do_this_always();
}
}
hm, isn't this similar/same as the python version?
try{
doSomething();
scope(success) "if no Exception thrown".writeln;
}
catch(Exception e)
{
...
}
Sep 05 2016









Basile B. <b2.temp gmx.com> 