Try blocks are trying

bauss jj_1337 at live.dk
Mon Oct 11 11:05:47 UTC 2021


On Monday, 11 October 2021 at 09:27:30 UTC, FeepingCreature wrote:
> On Monday, 11 October 2021 at 09:23:27 UTC, Imperatorn wrote:
>> On Monday, 11 October 2021 at 09:21:48 UTC, FeepingCreature 
>> wrote:
>>> On Monday, 11 October 2021 at 08:55:56 UTC, Imperatorn wrote:
>>>> In that case you would just declare x outside and do the 
>>>> call in the try
>>>
>>> Thus once again demonstrating that for a language that had a 
>>> major version change over it, D2 really doesn't care about 
>>> immutable.
>>
>> I don't know about that. But it's pretty standard for try to 
>> introduce a scope.
>
> The problem is if you want to use immutable types at all, this 
> forces you to either use awkward nested function idioms with 
> tuple returns for more than one variable, put the entire 
> remaining function body in the `try` block. It makes it 
> impossible to keep `try` small.
>
> One possible solution would be a way to try/catch as an 
> expression:
>
> ```
> auto x = frgl().tryCatch(Exception exc: return exc;);
> ```
>
> But D has no precedent for statements embedded in expressions 
> like this, so it'd be a major language shift.
>
> `export try` is the only feasible approach I can see offhand.

Using alias this, opAssign and a boolean value you can actually 
do something like this:

```d
public struct BindOnce(T)
{
     private bool _isSet;
     private T _value;

     alias _value this;

     void opAssign(T rhs)
     {
         if (_isSet)
         {
             throw new Error("The value has already been set.");
         }

         _isSet = true;
         _value = rhs;
     }

     string toString() { return to!string(_value); } // Required 
for writeln
}
```

Example Usage:

```
int getNumber(int input)
{
     if (input == 0) throw new Exception("This function doesn't 
allow multiplications of zero.");
     return input * 2;
}

void main()
{
     BindOnce!int n;
     try
     {
         n = getNumber(20);
         //n = getNumber(40); // Uncommenting this line will throw 
the error "The value has already been set."

         writeln(n);
     }
     catch (Exception e)
     {
         writeln(e);
         writeln(n);
     }
}
```

Of course this assumes you're able to allow runtime errors and 
that you don't blindly catches them and ignores them either 
(which you shouldn't as Error shouldn't be recoverable!)


More information about the Digitalmars-d mailing list