Thread overview | |||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
January 10, 2013 Throwing specific Error Obejct for asserts | ||||
---|---|---|---|---|
| ||||
Now that we have version assert, we can customize the assert flow to throw a more specific error: Before: //---- auto opSlice(size_t i, size_t j) { assert(i <= j); } //---- After: //---- auto opSlice(size_t i, size_t j) { version(assert) if (i > j) throw new RangeError(); } //---- Now, instead of having a generic AssertError (with or without a message), we have a statically typed RangeError. Yay! I have 2 problems with this though: 1) It is verbose as shit. 2) Using a if shifts the logic from checking the valid condition, to checking if things are *in*valid condition. eg: (i <= j) vs (i > j). If find this change of flow VERY disruptive. And error prone if migrating a condition that contains "&&" or "||". So question: Why don't we have, just like for enforce, the possibility of simply writing: //---- assert(i <= j, new RangeError()); //---- Seems like a win-win to me... ...Or would this be disruptive with things like "onAssertError" or "setAssertHandler" ... ? |
January 10, 2013 Re: Throwing specific Error Obejct for asserts | ||||
---|---|---|---|---|
| ||||
Posted in reply to monarch_dodra | monarch_dodra:
> After:
> //----
> auto opSlice(size_t i, size_t j)
> {
> version(assert)
> if (i > j)
> throw new RangeError();
> }
But now opSlice can't be nothrow, nor transitively all the code that calls that :-(
Bye,
bearophile
|
January 10, 2013 Re: Throwing specific Error Obejct for asserts | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | On Thursday, 10 January 2013 at 14:28:44 UTC, bearophile wrote:
> monarch_dodra:
>
>> After:
>> //----
>> auto opSlice(size_t i, size_t j)
>> {
>> version(assert)
>> if (i > j)
>> throw new RangeError();
>> }
>
> But now opSlice can't be nothrow, nor transitively all the code that calls that :-(
>
> Bye,
> bearophile
It can because RangeError is an *Error*.
I actually filed that one, and walter fixed it shortly after. ;)
|
January 10, 2013 Re: Throwing specific Error Obejct for asserts | ||||
---|---|---|---|---|
| ||||
Posted in reply to monarch_dodra | On Thursday, 10 January 2013 at 14:31:04 UTC, monarch_dodra wrote: > On Thursday, 10 January 2013 at 14:28:44 UTC, bearophile wrote: >> monarch_dodra: >> >>> After: >>> //---- >>> auto opSlice(size_t i, size_t j) >>> { >>> version(assert) >>> if (i > j) >>> throw new RangeError(); >>> } >> >> But now opSlice can't be nothrow, nor transitively all the code that calls that :-( >> >> Bye, >> bearophile > > It can because RangeError is an *Error*. > > I actually filed that one, and walter fixed it shortly after. ;) Fixed by Martin Nowak actually. Apologies. https://github.com/D-Programming-Language/dmd/commit/d77b7c2bf456e99495d8a6644a6304995d1a3b20 |
January 10, 2013 Re: Throwing specific Error Obejct for asserts | ||||
---|---|---|---|---|
| ||||
Posted in reply to monarch_dodra | On Thursday, 10 January 2013 at 14:31:04 UTC, monarch_dodra wrote:
> On Thursday, 10 January 2013 at 14:28:44 UTC, bearophile wrote:
>> monarch_dodra:
>>
>>> After:
>>> //----
>>> auto opSlice(size_t i, size_t j)
>>> {
>>> version(assert)
>>> if (i > j)
>>> throw new RangeError();
>>> }
>>
>> But now opSlice can't be nothrow, nor transitively all the code that calls that :-(
>>
>> Bye,
>> bearophile
>
> It can because RangeError is an *Error*.
Apologies again, if my answer was not clear: Nothrow means the function can't throw *exceptions*, but errors are fair game.
For example, this compiles:
//----
import core.exception;
void foo() nothrow
{
throw new RangeError();
}
void main()
{
foo();
}
//----
|
January 10, 2013 Re: Throwing specific Error Obejct for asserts | ||||
---|---|---|---|---|
| ||||
Posted in reply to monarch_dodra | On 1/10/13 6:23 AM, monarch_dodra wrote:
> So question: Why don't we have, just like for enforce, the possibility
> of simply writing:
> //----
> assert(i <= j, new RangeError());
> //----
Define another function...?
Andrei
|
January 10, 2013 Re: Throwing specific Error Obejct for asserts | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrei Alexandrescu | On Thursday, 10 January 2013 at 15:54:21 UTC, Andrei Alexandrescu wrote:
> On 1/10/13 6:23 AM, monarch_dodra wrote:
>> So question: Why don't we have, just like for enforce, the possibility
>> of simply writing:
>> //----
>> assert(i <= j, new RangeError());
>> //----
>
> Define another function...?
>
> Andrei
Well, I would. I'd write an overload, but I can't, because assert is built-in.
I'd have to provide a new name (such as assertError). This would not be as convenient as having an overload. That, and a library function can't match assert's built-in functionality. For example:
//----
struct S()
{
version(assert)
bool isValid = false; //debug only variable
void foo()
{
assertError(isValid, new RangeError()); //HERE
}
}
//----
The problem is that at best, assertError can be a noop-implementation in release, but the call is still there. The first argument will still get evaluated. Further more, it may not even compile...
|
January 10, 2013 Re: Throwing specific Error Obejct for asserts | ||||
---|---|---|---|---|
| ||||
Posted in reply to monarch_dodra | 10-Jan-2013 20:11, monarch_dodra пишет: > On Thursday, 10 January 2013 at 15:54:21 UTC, Andrei Alexandrescu wrote: >> On 1/10/13 6:23 AM, monarch_dodra wrote: >>> So question: Why don't we have, just like for enforce, the possibility >>> of simply writing: >>> //---- >>> assert(i <= j, new RangeError()); >>> //---- >> >> Define another function...? >> >> Andrei > > Well, I would. I'd write an overload, but I can't, because assert is > built-in. > > I'd have to provide a new name (such as assertError). This would not be > as convenient as having an overload. That, and a library function can't > match assert's built-in functionality. For example: > > //---- > struct S() > { > version(assert) > bool isValid = false; //debug only variable > > void foo() > { > assertError(isValid, new RangeError()); //HERE > } > } > //---- > > The problem is that at best, assertError can be a noop-implementation in > release, but the call is still there. The first argument will still get > evaluated. Further more, it may not even compile... lazy keyword to the rescue. -- Dmitry Olshansky |
January 10, 2013 Re: Throwing specific Error Obejct for asserts | ||||
---|---|---|---|---|
| ||||
Posted in reply to Dmitry Olshansky | On Thursday, 10 January 2013 at 17:46:54 UTC, Dmitry Olshansky wrote:
> 10-Jan-2013 20:11, monarch_dodra пишет:
>> On Thursday, 10 January 2013 at 15:54:21 UTC, Andrei Alexandrescu wrote:
>>> On 1/10/13 6:23 AM, monarch_dodra wrote:
>>>> So question: Why don't we have, just like for enforce, the possibility
>>>> of simply writing:
>>>> //----
>>>> assert(i <= j, new RangeError());
>>>> //----
>>>
>>> Define another function...?
>>>
>>> Andrei
>>
>> Well, I would. I'd write an overload, but I can't, because assert is
>> built-in.
>>
>> I'd have to provide a new name (such as assertError). This would not be
>> as convenient as having an overload. That, and a library function can't
>> match assert's built-in functionality. For example:
>>
>> //----
>> struct S()
>> {
>> version(assert)
>> bool isValid = false; //debug only variable
>>
>> void foo()
>> {
>> assertError(isValid, new RangeError()); //HERE
>> }
>> }
>> //----
>>
>> The problem is that at best, assertError can be a noop-implementation in
>> release, but the call is still there. The first argument will still get
>> evaluated. Further more, it may not even compile...
>
> lazy keyword to the rescue.
Still doesn't compile though...
And using "assertError" also still isn't as convenient as "assert"
|
January 10, 2013 Re: Throwing specific Error Obejct for asserts | ||||
---|---|---|---|---|
| ||||
Posted in reply to monarch_dodra | On 1/10/13 10:03 AM, monarch_dodra wrote: > Still doesn't compile though... See enforce's implementation. > And using "assertError" also still isn't as convenient as "assert" Please. You have the entire vocabulary minus assert. Andrei |
Copyright © 1999-2021 by the D Language Foundation