nothrow and std.exception.ifThrown

Steven Schveighoffer schveiguy at gmail.com
Fri Apr 30 13:42:49 UTC 2021


On 4/30/21 9:24 AM, Meta wrote:
> On Friday, 30 April 2021 at 13:05:00 UTC, Steven Schveighoffer wrote:
>> On 4/29/21 1:50 PM, Meta wrote:
>>
>>>
>>> The reason for this, apparently, is in the definition of `ifThrown`:
>>> ```
>>> CommonType!(T1, T2) ifThrown(E : Throwable = Exception, T1, T2)(lazy 
>>> scope T1 expression, lazy scope T2 errorHandler) nothrow
>>> ```
>>>
>>> It's not marked as `nothrow` in the function's definition, so even if 
>>> the delegate passed to ifThrown _is_ nothrow, the compiler can't 
>>> tell. There's no easy way around this that I can think of OTOH that 
>>> doesn't involve some effort on your part.
>>
>> Wait, I don't get what you are saying. You mean it should be marked 
>> nothrow? It's a template, so it *should* be inferred nothrow if it 
>> were actually nothrow.
>>
>> The current definition is not marked nothrow as you alluded, and when 
>> I do mark it nothrow, it complains that the lazy parameter used for 
>> the exception handler is not nothrow.
>>
>> It seems there's no way to infer the throwing of the lazy parameter, 
>> lazy parameters are never nothrow.
>>
>> The higher order function DIP would I think help with this.
> 
> Change it to a delegate and it's the same thing. ifThrown being a 
> template is irrelevant in this case because it is accepting the handler 
> as a function argument, not a template argument. You:
> 
> 1. Need to make it a delegate instead of a lazy argument.
> 
> 2. Need to mark the delegate as nothrow.
> 
> For the function to be inferred as nothrow.

My point is that I think marking the *function* nothrow is not correct, 
it's the second parameter that dictates the throwing of the result.

And you can probably fix the second parameter to be a templated delegate:

```d
CommonType!(T1, T2) ifThrown(E : Throwable = Exception, T1, T2)(lazy 
scope T1 expression, scope T2 errorHandler) if 
(is(typeof(errorHandler(E.init))))
```

And of course, we get into chicken-and-egg problems with this because if 
you pass in a lambda, there's no types for it to figure this stuff out. 
Another option is to overload on the delegate, but meh. I'd really like 
to see a language change that says "infer the attributes of this 
function based on the fact that it calls the delegate passed in."

-Steve


More information about the Digitalmars-d-learn mailing list