digitalmars.D - Throwing specific Error Obejct for asserts
- monarch_dodra (33/34) Jan 10 2013 Now that we have version assert, we can customize the assert flow
- bearophile (5/13) Jan 10 2013 But now opSlice can't be nothrow, nor transitively all the code
- monarch_dodra (3/16) Jan 10 2013 It can because RangeError is an *Error*.
- monarch_dodra (3/22) Jan 10 2013 Fixed by Martin Nowak actually. Apologies.
- monarch_dodra (15/33) Jan 10 2013 Apologies again, if my answer was not clear: Nothrow means the
- Andrei Alexandrescu (3/8) Jan 10 2013 Define another function...?
- monarch_dodra (22/31) Jan 10 2013 Well, I would. I'd write an overload, but I can't, because assert
- Dmitry Olshansky (4/34) Jan 10 2013 lazy keyword to the rescue.
- monarch_dodra (4/48) Jan 10 2013 Still doesn't compile though...
- Andrei Alexandrescu (4/6) Jan 10 2013 Please. You have the entire vocabulary minus assert.
- monarch_dodra (3/7) Jan 10 2013 Fine. I know how to take a hint.
- Andrei Alexandrescu (12/20) Jan 10 2013 OK OK now you're making me feel bad for being abrupt :o). There is a
- Simen Kjaeraas (16/59) Jan 10 2013 n't
- monarch_dodra (3/12) Jan 10 2013 As a matter of fact, yes. Yes I am. Are you using 2.061 ?
- monarch_dodra (2/19) Jan 10 2013 Scratch that. Template was throwing me off.
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 (ij). If find this change of flow VERY disruptive. And errorprone 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" ... ?
Jan 10 2013
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
Jan 10 2013
On Thursday, 10 January 2013 at 14:28:44 UTC, bearophile wrote:monarch_dodra:It can because RangeError is an *Error*. I actually filed that one, and walter fixed it shortly after. ;)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
Jan 10 2013
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:Fixed by Martin Nowak actually. Apologies. https://github.com/D-Programming-Language/dmd/commit/d77b7c2bf456e99495d8a6644a6304995d1a3b20monarch_dodra:It can because RangeError is an *Error*. I actually filed that one, and walter fixed it shortly after. ;)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
Jan 10 2013
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: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(); } //----monarch_dodra:It can because RangeError is an *Error*.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
Jan 10 2013
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
Jan 10 2013
On Thursday, 10 January 2013 at 15:54:21 UTC, Andrei Alexandrescu wrote:On 1/10/13 6:23 AM, monarch_dodra wrote: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...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
Jan 10 2013
10-Jan-2013 20:11, monarch_dodra пишет:On Thursday, 10 January 2013 at 15:54:21 UTC, Andrei Alexandrescu wrote:lazy keyword to the rescue. -- Dmitry OlshanskyOn 1/10/13 6:23 AM, monarch_dodra wrote: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...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
Jan 10 2013
On Thursday, 10 January 2013 at 17:46:54 UTC, Dmitry Olshansky wrote:10-Jan-2013 20:11, monarch_dodra пишет:Still doesn't compile though... And using "assertError" also still isn't as convenient as "assert"On Thursday, 10 January 2013 at 15:54:21 UTC, Andrei Alexandrescu wrote:lazy keyword to the rescue.On 1/10/13 6:23 AM, monarch_dodra wrote: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...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
Jan 10 2013
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
Jan 10 2013
On Thursday, 10 January 2013 at 18:31:17 UTC, Andrei Alexandrescu wrote:Fine. I know how to take a hint.And using "assertError" also still isn't as convenient as "assert"Please. You have the entire vocabulary minus assert. Andrei
Jan 10 2013
On 1/10/13 11:56 AM, monarch_dodra wrote:On Thursday, 10 January 2013 at 18:31:17 UTC, Andrei Alexandrescu wrote:OK OK now you're making me feel bad for being abrupt :o). There is a back story to this. Generally we're trying to stem a tide of big trenches built around small points in this forum (things like the "one-click" issue in the changelog, hiding member variable names, etc). In such discussions we sometimes latch on one simple thing and set great store to it, to the point of losing a sense of proportion to its actual importance. There must be a way to say: "OK, the point has been understood and well taken, but it has not been convincing enough" without getting anyone angry and without engendering a rehash of the argument. AndreiFine. I know how to take a hint.And using "assertError" also still isn't as convenient as "assert"Please. You have the entire vocabulary minus assert. Andrei
Jan 10 2013
On 2013-01-10, 19:03, monarch_dodra wrote:On Thursday, 10 January 2013 at 17:46:54 UTC, Dmitry Olshansky wrote:10-Jan-2013 20:11, monarch_dodra =D0=BF=D0=B8=D1=88=D0=B5=D1=82: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 =Well, I would. I'd write an overload, but I can't, because assert is=possibility of simply writing: //---- assert(i <=3D j, new RangeError()); //----Define another function...? Andreibebuilt-in. I'd have to provide a new name (such as assertError). This would not=n'tas convenient as having an overload. That, and a library function ca=n =match assert's built-in functionality. For example: //---- struct S() { version(assert) bool isValid =3D false; //debug only variable void foo() { assertError(isValid, new RangeError()); //HERE } } //---- The problem is that at best, assertError can be a noop-implementatio=getin release, but the call is still there. The first argument will still =So you're saying this does compile for you, with -release? struct S( ) { version(assert) bool isValid =3D false; void foo() { assert(isValid); } } It certainly does not for me. -- = SimenStill doesn't compile though...evaluated. Further more, it may not even compile...lazy keyword to the rescue.
Jan 10 2013
On Thursday, 10 January 2013 at 19:31:18 UTC, Simen Kjaeraas wrote:So you're saying this does compile for you, with -release? struct S( ) { version(assert) bool isValid = false; void foo() { assert(isValid); } } It certainly does not for me.As a matter of fact, yes. Yes I am. Are you using 2.061 ?
Jan 10 2013
On Thursday, 10 January 2013 at 19:47:46 UTC, monarch_dodra wrote:On Thursday, 10 January 2013 at 19:31:18 UTC, Simen Kjaeraas wrote:Scratch that. Template was throwing me off.So you're saying this does compile for you, with -release? struct S( ) { version(assert) bool isValid = false; void foo() { assert(isValid); } } It certainly does not for me.As a matter of fact, yes. Yes I am. Are you using 2.061 ?
Jan 10 2013