digitalmars.D - Versioned std.exception.bailOut()?
- bearophile (43/43) Jun 15 2012 This is the std.typecons.Nullable.get() method:
- Dmitry Olshansky (7/23) Jun 15 2012 Stupidity. An exemplar one.
- Dmitry Olshansky (7/11) Jun 15 2012 If that is sole concern, I suggest do a pull that makes enforce vs
- bearophile (8/13) Jun 15 2012 Nullable isn't the only problem, there are similar problems with
- Dmitry Olshansky (5/14) Jun 15 2012 why would uniform have to do anything with nullable?
- Kagamin (2/6) Jun 15 2012 And how the assert helps with inlining?
- Jacob Carlborg (4/10) Jun 15 2012 Perhaps throwing an exception prevents inlining ?
- Jonathan M Davis (7/17) Jun 15 2012 It's the fact that enforce is lazy which prevents inlining (which really...
- bearophile (8/18) Jun 15 2012 enforce() sometimes is used as an assert you can't disable (as in
- =?UTF-8?B?QWxleCBSw7hubmUgUGV0ZXJzZW4=?= (11/28) Jun 15 2012 No, Jonathan's point is that enforce() can be used with both Errors and
- Jonathan M Davis (24/43) Jun 15 2012 No. enforce and assert are fundamentaly different. One is used for throw...
This is the std.typecons.Nullable.get() method: property ref inout(T) get() inout pure safe { enforce(!isNull); return _value; } And this is the std.exception.enforce() and bailOut(): T enforce(T, string file = __FILE__, size_t line = __LINE__) (T value, lazy const(char)[] msg = null) safe pure { if (!value) bailOut(file, line, msg); return value; } private void bailOut(string file, size_t line, in char[] msg) safe pure { throw new Exception(msg ? msg.idup : "Enforcement failed", file, line); } What do you think about replacing the bailOut() with: version (halting_enforce) { private void bailOut(string file, size_t line, in char[] msg) safe pure nothrow { assert(0, msg ? msg : "Enforcement failed"); } } else { private void bailOut(string file, size_t line, in char[] msg) safe pure { throw new Exception(msg ? msg.idup : "Enforcement failed", file, line); } } Even if this version is not documented in Phobos docs (because the inliner someday will be better), today it allows methods that must be fast like Nullable.get() to be inlined (but I have not tested this), regaining the lost performance. Bye, bearophile
Jun 15 2012
On 15.06.2012 16:17, bearophile wrote:What do you think about replacing the bailOut() with: version (halting_enforce) { private void bailOut(string file, size_t line, in char[] msg) safe pure nothrow { assert(0, msg ? msg : "Enforcement failed"); } } else { private void bailOut(string file, size_t line, in char[] msg) safe pure { throw new Exception(msg ? msg.idup : "Enforcement failed", file, line); } }Stupidity. An exemplar one. Anyone caught trying to hijacking core exception handling primive (that by the way check things like file I/O) in std library should be shot on sight. -- Dmitry Olshansky
Jun 15 2012
On 15.06.2012 16:17, bearophile wrote:Even if this version is not documented in Phobos docs (because the inliner someday will be better), today it allows methods that must be fast like Nullable.get() to be inlined (but I have not tested this), regaining the lost performance.If that is sole concern, I suggest do a pull that makes enforce vs assert decision accessible from the outside: NotNull!(T, NotNull.Strict) //asserts NotNull!T //throws -- Dmitry Olshansky
Jun 15 2012
Dmitry Olshansky:If that is sole concern, I suggest do a pull that makes enforce vs assert decision accessible from the outside: NotNull!(T, NotNull.Strict) //asserts NotNull!T //throwsNullable isn't the only problem, there are similar problems with std.random.uniform. How do you tell uniform() what kind of Nullable to use? ---------------------Perhaps throwing an exception prevents inlining ?With DMD. Bye, bearophile
Jun 15 2012
On 15.06.2012 18:27, bearophile wrote:Dmitry Olshansky:why would uniform have to do anything with nullable? If anything it's handled like always via tempaltes. -- Dmitry OlshanskyIf that is sole concern, I suggest do a pull that makes enforce vs assert decision accessible from the outside: NotNull!(T, NotNull.Strict) //asserts NotNull!T //throwsNullable isn't the only problem, there are similar problems with std.random.uniform. How do you tell uniform() what kind of Nullable to use?
Jun 15 2012
On Friday, 15 June 2012 at 12:17:32 UTC, bearophile wrote:Even if this version is not documented in Phobos docs (because the inliner someday will be better), today it allows methods that must be fast like Nullable.get() to be inlined (but I have not tested this), regaining the lost performance.And how the assert helps with inlining?
Jun 15 2012
On 2012-06-15 14:55, Kagamin wrote:On Friday, 15 June 2012 at 12:17:32 UTC, bearophile wrote:Perhaps throwing an exception prevents inlining ? -- /Jacob CarlborgEven if this version is not documented in Phobos docs (because the inliner someday will be better), today it allows methods that must be fast like Nullable.get() to be inlined (but I have not tested this), regaining the lost performance.And how the assert helps with inlining?
Jun 15 2012
On Friday, June 15, 2012 15:50:17 Jacob Carlborg wrote:On 2012-06-15 14:55, Kagamin wrote:It's the fact that enforce is lazy which prevents inlining (which really does need to be fixed or enforce is going to continue to be a performance problem). However, this suggestion is clearly bad, because it's suggesting turning an exception into an assertion, which is _very_ broken thing to do. Assertions and exceptions are two _very_ different things and should be treated as such. - Jonathan M DavisOn Friday, 15 June 2012 at 12:17:32 UTC, bearophile wrote:Perhaps throwing an exception prevents inlining ?Even if this version is not documented in Phobos docs (because the inliner someday will be better), today it allows methods that must be fast like Nullable.get() to be inlined (but I have not tested this), regaining the lost performance.And how the assert helps with inlining?
Jun 15 2012
Jonathan M Davis:It's the fact that enforce is lazy which prevents inlining (which really does need to be fixed or enforce is going to continue to be a performance problem).Then my "solution" solves nothing. Thank you Jonathan.However, this suggestion is clearly bad, because it's suggesting turning an exception into an assertion, which is _very_ broken thing to do. Assertions and exceptions are two _very_ different things and should be treated as such.enforce() sometimes is used as an assert you can't disable (as in Nullable.get, I think). So maybe such cases are better handled introducing two levels of asserts, "light asserts" and "strong asserts". Bye, bearophile
Jun 15 2012
On 15-06-2012 19:31, bearophile wrote:Jonathan M Davis:No, Jonathan's point is that enforce() can be used with both Errors and Exceptions. When used with Errors, we're talking about logic errors (effectively the same as an assert, with the exception that it isn't compiled out in release builds), while when we're talking about Exceptions, the error is recoverable. See for example some uses of enforce() in std.stdio.File. -- Alex Rønne Petersen alex lycus.org http://lycus.orgIt's the fact that enforce is lazy which prevents inlining (which really does need to be fixed or enforce is going to continue to be a performance problem).Then my "solution" solves nothing. Thank you Jonathan.However, this suggestion is clearly bad, because it's suggesting turning an exception into an assertion, which is _very_ broken thing to do. Assertions and exceptions are two _very_ different things and should be treated as such.enforce() sometimes is used as an assert you can't disable (as in Nullable.get, I think). So maybe such cases are better handled introducing two levels of asserts, "light asserts" and "strong asserts". Bye, bearophile
Jun 15 2012
On Friday, June 15, 2012 19:31:58 bearophile wrote:Jonathan M Davis:No. enforce and assert are fundamentaly different. One is used for throwing an exception, which indicates an error that occurs while running the program, whereas the other one throws an AssertError in non-release mode, which indicates a bug in the program. enforce should be used purely for error handling, and assert should be used purely for checking the validity of your code. Pretty much the only case where it's really a question of whether one or the other should be used is when determining whether a function should be using design-by-contract or defensive programming. If it's design-by-contract, then failing the condition of the contract is a bug, and an assertion is used. If it's defensive programming, then the function treats its parameters as if they were user input, verifies them, and then throws if the conditions aren't met, thereby indicating an error condition to the caller. The choice between the two is a matter of whether the function treats its input as user input or not. In the case of std.typecons.Nullable, it's treating its state as something relating to the program's input such that it is not necessarily a bug in the program if it attempts to get Nullable's value when it's null. So, the programmer does not need to check whether the Nullable is null or not before using it if they don't want to. If it were using assert, then it would be saying that programmer must guarantee that its state is not null before its value is fetched, or it's a bug. The two approaches mean fundamentally different things to how Nullable is designed and used. - Jonathan M DavisIt's the fact that enforce is lazy which prevents inlining (which really does need to be fixed or enforce is going to continue to be a performance problem).Then my "solution" solves nothing. Thank you Jonathan.However, this suggestion is clearly bad, because it's suggesting turning an exception into an assertion, which is _very_ broken thing to do. Assertions and exceptions are two _very_ different things and should be treated as such.enforce() sometimes is used as an assert you can't disable (as in Nullable.get, I think). So maybe such cases are better handled introducing two levels of asserts, "light asserts" and "strong asserts".
Jun 15 2012