Thread overview
Type Inference and Try Blocks
Jan 20, 2020
Henry Claesson
Jan 21, 2020
Adam D. Ruppe
Jan 21, 2020
user1234
Jan 21, 2020
Mitacha
Jan 22, 2020
Henry Claesson
January 20, 2020
This isn't a D-specific "problem", but there may be D-specific solutions.
I have a function `doSomething()` that returns a Voldemort type, and this same function also throws. So, there's this:

try {
    auto foo = doSomething();
} catch (AnException e) {
    // Do stuff
}

The problem that I'm encountering is that I'd like, assuming no exception was thrown, to use foo outside the `try` (or `finally`) block to avoid nesting as any operations on `foo` from that point onward may also throw. Are there any constructs that act as alternatives to try/catch/finally so that I can do this?

(This issue could very well stem from poor design and not being familiar with programming using exceptions. So feel free to ignore.)

Thanks
January 21, 2020
On Monday, 20 January 2020 at 23:16:07 UTC, Henry Claesson wrote:
> This isn't a D-specific "problem", but there may be D-specific solutions.
> I have a function `doSomething()` that returns a Voldemort type, and this same function also throws. So, there's this:
>
> try {
>     auto foo = doSomething();
> } catch (AnException e) {
>     // Do stuff
> }

I'd suggest just doing

try {
    auto foo = doSomething();
    // use foo right here!
} catch(AnException e) {
    // do other stuff
} catch(OtherException e) {
   // reminder you can do this too btw
}


That is, put ALL the use of foo inside the one try block, don't keep nesting - only try/catch when you can specifically recover or add information to it at that particular point. If you can't do that, just keep going. try/catch over individual functions is often (though not always) poor design.

If you really do need the variable outside, you can do

typeof(doSomething(args...)) foo;
try {
  foo = doSomething()
}

too to declare the var outside. But first I'd try getting it all in that try block.

You can also do helper functions for some cases too btw

auto getfoo() {
   try return doSomething();
   catch(MyException e) { return alternative(); }
}

and remember you can define that right inside the function; nested functons rock.

January 21, 2020
On Monday, 20 January 2020 at 23:16:07 UTC, Henry Claesson wrote:
> This isn't a D-specific "problem", but there may be D-specific solutions.
> I have a function `doSomething()` that returns a Voldemort type, and this same function also throws. So, there's this:
>
> try {
>     auto foo = doSomething();
> } catch (AnException e) {
>     // Do stuff
> }
>
> The problem that I'm encountering is that I'd like, assuming no exception was thrown, to use foo outside the `try` (or `finally`) block to avoid nesting as any operations on `foo` from that point onward may also throw. Are there any constructs that act as alternatives to try/catch/finally so that I can do this?
>
> (This issue could very well stem from poor design and not being familiar with programming using exceptions. So feel free to ignore.)
>
> Thanks

The problem you have is not called type inference, it's called "scope".
In a particular scope you have symbols "S". In a sub scope you also have "S" but in the parent scope "S" are not existing anymore.

January 21, 2020
On Monday, 20 January 2020 at 23:16:07 UTC, Henry Claesson wrote:
> This isn't a D-specific "problem", but there may be D-specific solutions.
> I have a function `doSomething()` that returns a Voldemort type, and this same function also throws. So, there's this:
>
> try {
>     auto foo = doSomething();
> } catch (AnException e) {
>     // Do stuff
> }
>
> The problem that I'm encountering is that I'd like, assuming no exception was thrown, to use foo outside the `try` (or `finally`) block to avoid nesting as any operations on `foo` from that point onward may also throw. Are there any constructs that act as alternatives to try/catch/finally so that I can do this?
>
> (This issue could very well stem from poor design and not being familiar with programming using exceptions. So feel free to ignore.)
>
> Thanks

You could try using `ifThrown` from `std.exception`. It lets you turn statement based exception handling into expression based one. So, if there is some "default" value in your case you could return that.

auto foo = doSomething().ifThrown!AnException("defaultValue");
January 22, 2020
Thank you for the help and input, Adam and Mitacha. I don't know why I thought I must use `try` with every throwable function call instead "bundling" those calls into one `try` block. Not "bundling" defeats one of the benefits of exceptions. Also, `ifThrown` is quite interesting.
Again, thank you!