digitalmars.D - exceptions vs error codes
- Superstar64 (5/5) Jul 09 2016 In terms of performance and code generation exceptions are faster
- ketmar (1/1) Jul 09 2016 what i just did read?! O_O
- Seb (4/5) Jul 09 2016 Don't be drunken on the NG! If you take the time to answer, do so
- ketmar (2/3) Jul 10 2016 no. i was born ideal and all-knowledgeable.
- Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= (4/9) Jul 10 2016 Well, I am sure you don't want ketmar back to where he was as a
- Jack Stouffer (6/11) Jul 09 2016 If I understand correctly, you want C/Go style error codes when a
- ketmar (4/4) Jul 10 2016 it seems that OP wants a kind of compiler switch (or pragma, or
- Chris Wright (4/8) Jul 10 2016 But as an annotation like @nogc it would work.
- ketmar (4/6) Jul 10 2016 as a side note: it is even not guaranteed that one *can* catch
- Chris Wright (5/12) Jul 10 2016 Array bounds errors, then. For associative arrays, that's a runtime
- ketmar (12/21) Jul 11 2016 any Error. spec clearly says that throwing Error doesn't
- Max Samukha (4/10) Jul 13 2016 Undefined does not imply corrupt. There are many examples of
- ketmar (6/7) Jul 13 2016 undefined means "undefined". there is nothing more to save,
- Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= (4/11) Jul 13 2016 Undefined by the language is not the same as unknown in a
- ketmar (7/10) Jul 13 2016 "program is in undefined state"? that is what written in the
- Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= (4/15) Jul 13 2016 That is a meaningless statement. The program is never in a state.
- ketmar (3/5) Jul 13 2016 no.
- Max Samukha (6/13) Jul 13 2016 Not true. Undefined implies there *may* be something to save.
- ketmar (7/11) Jul 13 2016 that's why they aren't portable. and written by bad programmers,
- Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= (8/11) Jul 13 2016 Wrong. Just because a language-spec says a compiler writer does
- ketmar (3/7) Jul 13 2016 you can't. by definition.
- Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= (3/10) Jul 13 2016 If it is undefined, then there is no definition. Are you trolling
- Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= (4/15) Jul 13 2016 Please not that «undefined» does not mean «required to be
- Chris Wright (16/23) Jul 13 2016 This is just plain wrong. The spec explicitly talks about catching Error...
- ketmar (10/10) Jul 13 2016 On Wednesday, 13 July 2016 at 13:13:45 UTC, Chris Wright wrote:
- Chris Wright (3/9) Jul 13 2016 Point to the place in the spec that it says that this is true of Error
- ketmar (7/21) Jul 13 2016 https://dlang.org/library/object/throwable.html
- Chris Wright (12/18) Jul 13 2016 So this is two separate things coming together:
- Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= (4/9) Jul 10 2016 Yes, this has been discussed quite heavily in the past. It is
- Walter Bright (2/5) Jul 10 2016 When has D ever done anything right in your eyes? Just curious!
- Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= (14/21) Jul 10 2016 The original plan, to redo C++ by creating a simpler formulation
- Walter Bright (2/5) Jul 11 2016 So what's stopping you from using Scheme?
- Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= (3/9) Jul 11 2016 Nothing is stopping me from using Lisp where appropriate. Why are
- phant0m (10/15) Jul 10 2016 Personally, I don't understand the need for exceptions at all.
- Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= (6/12) Jul 10 2016 No, not if you use RAII.
- Chris Wright (12/18) Jul 10 2016 We separate execution into tasks (which could be messages in SQS, or RPC...
- Superstar64 (3/8) Jul 10 2016 I made a DIP for this:
- Steven Schveighoffer (9/13) Jul 11 2016 Swift does exactly this. It doesn't have exceptions, but mimics them by
- Walter Bright (3/5) Jul 11 2016 If you want to return an error code, return an error code. No language
- Chris Wright (10/16) Jul 11 2016 I think the intent is to tell the compiler: the error case is very
- Walter Bright (2/11) Jul 11 2016 I really have no idea what the benefit is of telling the compiler that.
In terms of performance and code generation exceptions are faster in the regular path while error codes are faster in the error path. Would it be possible and a good idea to have a language feature that allows some exceptions to use error code code generation.
Jul 09 2016
On Sunday, 10 July 2016 at 06:31:34 UTC, ketmar wrote:what i just did read?! O_ODon't be drunken on the NG! If you take the time to answer, do so in a friendly and helpful way. Remember that you also started as a beginner!
Jul 09 2016
On Sunday, 10 July 2016 at 06:36:06 UTC, Seb wrote:Remember that you also started as a beginner!no. i was born ideal and all-knowledgeable.
Jul 10 2016
On Sunday, 10 July 2016 at 06:36:06 UTC, Seb wrote:On Sunday, 10 July 2016 at 06:31:34 UTC, ketmar wrote:Well, I am sure you don't want ketmar back to where he was as a beginner... O_owhat i just did read?! O_ODon't be drunken on the NG! If you take the time to answer, do so in a friendly and helpful way. Remember that you also started as a beginner!
Jul 10 2016
On Sunday, 10 July 2016 at 03:02:31 UTC, Superstar64 wrote:In terms of performance and code generation exceptions are faster in the regular path while error codes are faster in the error path. Would it be possible and a good idea to have a language feature that allows some exceptions to use error code code generation.If I understand correctly, you want C/Go style error codes when a function fails rather than exceptions? This is possible, it's just not used by Phobos. Just use std.variant and have your function return the value on success and the error value on failure.
Jul 09 2016
it seems that OP wants a kind of compiler switch (or pragma, or attribute) to magically turn `throw` into returning some kind of "error value". and we already has too much dangerous compiler switches like that (even one is too much, and we have two).
Jul 10 2016
On Sun, 10 Jul 2016 07:06:28 +0000, ketmar wrote:it seems that OP wants a kind of compiler switch (or pragma, or attribute) to magically turn `throw` into returning some kind of "error value". and we already has too much dangerous compiler switches like that (even one is too much, and we have two).But as an annotation like nogc it would work. You do need a try/catch in every annotated function to catch runtime exceptions like OutOfMemoryError.
Jul 10 2016
On Sunday, 10 July 2016 at 16:47:31 UTC, Chris Wright wrote:You do need a try/catch in every annotated function to catch runtime exceptions like OutOfMemoryError.as a side note: it is even not guaranteed that one *can* catch Error. and it is plainly wrong to try to continue execution after that, as program is in undefined state.
Jul 10 2016
On Sun, 10 Jul 2016 16:57:49 +0000, ketmar wrote:On Sunday, 10 July 2016 at 16:47:31 UTC, Chris Wright wrote:Array bounds errors, then. For associative arrays, that's a runtime method invocation. We'd have to implement every runtime method twice, or eliminate precompiled libraries, or accept that throwAsReturnValue requires every function to have a hidden try/catch.You do need a try/catch in every annotated function to catch runtime exceptions like OutOfMemoryError.as a side note: it is even not guaranteed that one *can* catch Error. and it is plainly wrong to try to continue execution after that, as program is in undefined state.
Jul 10 2016
On Sunday, 10 July 2016 at 21:31:57 UTC, Chris Wright wrote:On Sun, 10 Jul 2016 16:57:49 +0000, ketmar wrote:any Error. spec clearly says that throwing Error doesn't guarantee proper unwinding (and by that, it may skip as many catch blocks as it want), and program is in undefined state after catching Error. in DMD, it just happened to be implemented in a way that it is possible to catch many errors, get unwinding, and such. but it isn't a requirement. and, by the way, by writing different spec-compliant implementation, one can break alot of unittests, as many unittests catching AssertError. and no, i don't know how to write a reliable and spec-compliant unittest in D with `assert`s.On Sunday, 10 July 2016 at 16:47:31 UTC, Chris Wright wrote:Array bounds errors, then.You do need a try/catch in every annotated function to catch runtime exceptions like OutOfMemoryError.as a side note: it is even not guaranteed that one *can* catch Error. and it is plainly wrong to try to continue execution after that, as program is in undefined state.
Jul 11 2016
On Sunday, 10 July 2016 at 16:57:49 UTC, ketmar wrote:On Sunday, 10 July 2016 at 16:47:31 UTC, Chris Wright wrote:Undefined does not imply corrupt. There are many examples of programs that give you the last chance to save the state after a failure.You do need a try/catch in every annotated function to catch runtime exceptions like OutOfMemoryError.as a side note: it is even not guaranteed that one *can* catch Error. and it is plainly wrong to try to continue execution after that, as program is in undefined state.
Jul 13 2016
On Wednesday, 13 July 2016 at 07:14:04 UTC, Max Samukha wrote:Undefined does not imply corrupt.undefined means "undefined". there is nothing more to save, nothing more to do, as you can't rely on a single bit. this is... definition of undefined. relying on defined state with undefined behavior is not only dangerous, it is plainly invalid.
Jul 13 2016
On Wednesday, 13 July 2016 at 09:04:20 UTC, ketmar wrote:On Wednesday, 13 July 2016 at 07:14:04 UTC, Max Samukha wrote:Undefined by the language is not the same as unknown in a concrete instance. It simply means that such constructs are not part of the specified language.Undefined does not imply corrupt.undefined means "undefined". there is nothing more to save, nothing more to do, as you can't rely on a single bit. this is... definition of undefined. relying on defined state with undefined behavior is not only dangerous, it is plainly invalid.
Jul 13 2016
On Wednesday, 13 July 2016 at 09:12:56 UTC, Ola Fosheim Grøstad wrote:Undefined by the language is not the same as unknown in a concrete instance. It simply means that such constructs are not part of the specified language."program is in undefined state"? that is what written in the specs. and it means exactly that: *anything* can be messed up, including druntime internal things. the only thing one can really do here is invoke "exit" syscall as fast, as possible, or dereference zero pointer to get core dump.
Jul 13 2016
On Wednesday, 13 July 2016 at 09:53:31 UTC, ketmar wrote:On Wednesday, 13 July 2016 at 09:12:56 UTC, Ola Fosheim Grøstad wrote:That is a meaningless statement. The program is never in a state. The program is the input, the source code.Undefined by the language is not the same as unknown in a concrete instance. It simply means that such constructs are not part of the specified language."program is in undefined state"? that is what written in the specs.and it means exactly that: *anything* can be messed up, including druntime internal things. the only thing one can really do here is invoke "exit" syscall as fast, as possible, or dereference zero pointer to get core dump.That's an implementation detail.
Jul 13 2016
On Wednesday, 13 July 2016 at 10:14:24 UTC, Ola Fosheim Grøstad wrote:That is a meaningless statement. The program is never in a state. The program is the input, the source code.no.
Jul 13 2016
On Wednesday, 13 July 2016 at 09:04:20 UTC, ketmar wrote:On Wednesday, 13 July 2016 at 07:14:04 UTC, Max Samukha wrote:Not true. Undefined implies there *may* be something to save. That is why programs like Steinberg Cubase do not simply bail out on failure, but give users a chance to save a copy of their work. In my experience with Cubase, state needed for recovery survived the failure more often than not.Undefined does not imply corrupt.undefined means "undefined". there is nothing more to save, nothing more to do, as you can't rely on a single bit. this is... definition of undefined. relying on defined state with undefined behavior is not only dangerous, it is plainly invalid.
Jul 13 2016
On Wednesday, 13 July 2016 at 10:14:41 UTC, Max Samukha wrote:Undefined implies there *may* be something to save.but you have no way to know what.That is why programs like Steinberg Cubase do not simply bail out on failure, but give users a chance to save a copy of their work.that's why they aren't portable. and written by bad programmers, as there is never any need for "emergency save" in good designed progam: it keeps working logs and can replay everything user did if it crashed. sadly, most programmers aren't trained to write their software this way.
Jul 13 2016
On Wednesday, 13 July 2016 at 10:33:52 UTC, ketmar wrote:On Wednesday, 13 July 2016 at 10:14:41 UTC, Max Samukha wrote:Wrong. Just because a language-spec says a compiler writer does not have to care about a particular type of input does not mean that the compiler and programmer cannot verify the data to be valid. But hey, you don't even acknowledge that there is a difference between the machine and the program, so no hope of you getting into a reasonable argument on this one. ;-)Undefined implies there *may* be something to save.but you have no way to know what.
Jul 13 2016
On Wednesday, 13 July 2016 at 11:05:32 UTC, Ola Fosheim Grøstad wrote:Wrong. Just because a language-spec says a compiler writer does not have to care about a particular type of input does not mean that the compiler and programmer cannot verify the data to be valid.you can't. by definition.
Jul 13 2016
On Wednesday, 13 July 2016 at 11:06:54 UTC, ketmar wrote:On Wednesday, 13 July 2016 at 11:05:32 UTC, Ola Fosheim Grøstad wrote:If it is undefined, then there is no definition. Are you trolling me?Wrong. Just because a language-spec says a compiler writer does not have to care about a particular type of input does not mean that the compiler and programmer cannot verify the data to be valid.you can't. by definition.
Jul 13 2016
On Wednesday, 13 July 2016 at 11:16:03 UTC, Ola Fosheim Grøstad wrote:On Wednesday, 13 July 2016 at 11:06:54 UTC, ketmar wrote:Please not that «undefined» does not mean «required to be arbitrary».On Wednesday, 13 July 2016 at 11:05:32 UTC, Ola Fosheim Grøstad wrote:If it is undefined, then there is no definition. Are you trolling me?Wrong. Just because a language-spec says a compiler writer does not have to care about a particular type of input does not mean that the compiler and programmer cannot verify the data to be valid.you can't. by definition.
Jul 13 2016
On Sun, 10 Jul 2016 16:57:49 +0000, ketmar wrote:On Sunday, 10 July 2016 at 16:47:31 UTC, Chris Wright wrote:This is just plain wrong. The spec explicitly talks about catching Error (in the docs about TryStatement) and how to do it. I guess in the most general case, you're not guaranteed that your CPU won't catch fire in between the throw statement and the catch block? In which case we might as well throw out all programming -- and cognition, since I might get hit by a meteor while I'm pondering.You do need a try/catch in every annotated function to catch runtime exceptions like OutOfMemoryError.as a side note: it is even not guaranteed that one *can* catch Error.and it is plainly wrong to try to continue execution after that, as program is in undefined state.Also wrong. The spec defines the differences between Error and other Throwables. It involves how exception chaining works, if you throw an exception while handling an exception. It notably does not say that your program is in an undefined state after catching an Error. You might be saying that I could forget to clean up resources or restore invariants after an Error is thrown. But that's also true of any Throwable. Or a return statement. Again, if this sort of error bothers you so much that you refuse to write any code that could trigger it, you can't write *any* code.
Jul 13 2016
On Wednesday, 13 July 2016 at 13:13:45 UTC, Chris Wright wrote: as Error can be thrown anywhere along the way (think, for example, about RangeError in expression with side-effects), and stack unwinding is not guaranteed (but *may* happen, and may happen partially), the program *is* in undefined state. that is why Errors aren't usual Exceptions, and that is why you should not assume *anything* after Error is thrown. of course, some assumptions still can be made, but they all highly implementation-specific, and should be avoided in good code.
Jul 13 2016
On Wed, 13 Jul 2016 13:31:03 +0000, ketmar wrote:On Wednesday, 13 July 2016 at 13:13:45 UTC, Chris Wright wrote: as Error can be thrown anywhere along the way (think, for example, about RangeError in expression with side-effects), and stack unwinding is not guaranteed (but *may* happen, and may happen partially), the program *is* in undefined state. that is why Errors aren't usual Exceptions, and that is why you should not assume *anything* after Error is thrown.Point to the place in the spec that it says that this is true of Error and not other Throwables.
Jul 13 2016
On Wednesday, 13 July 2016 at 13:46:44 UTC, Chris Wright wrote:On Wed, 13 Jul 2016 13:31:03 +0000, ketmar wrote:https://dlang.org/library/object/throwable.html "In principle, one should not catch Throwable objects that are not derived from Exception, as they represent unrecoverable runtime errors. Certain runtime guarantees may fail to hold when these errors are thrown, making it unsafe to continue execution after catching them."On Wednesday, 13 July 2016 at 13:13:45 UTC, Chris Wright wrote: as Error can be thrown anywhere along the way (think, for example, about RangeError in expression with side-effects), and stack unwinding is not guaranteed (but *may* happen, and may happen partially), the program *is* in undefined state. that is why Errors aren't usual Exceptions, and that is why you should not assume *anything* after Error is thrown.Point to the place in the spec that it says that this is true of Error and not other Throwables.
Jul 13 2016
On Wed, 13 Jul 2016 13:50:00 +0000, ketmar wrote:https://dlang.org/library/object/throwable.html "In principle, one should not catch Throwable objects that are not derived from Exception, as they represent unrecoverable runtime errors. Certain runtime guarantees may fail to hold when these errors are thrown, making it unsafe to continue execution after catching them."So this is two separate things coming together: 1) If the runtime is sufficiently borked, it might be unable to unwind the stack. 2) If the runtime detects that it is borked, it will throw something derived from Error. You could just as well say that *no* runtime function is guaranteed to be safe to call because the runtime could be in an invalid state without having detected it. It's merely slightly riskier when an Error has been thrown. Specific to stack unwinding, it's pretty isolated from the rest of the runtime.
Jul 13 2016
On Sunday, 10 July 2016 at 03:02:31 UTC, Superstar64 wrote:In terms of performance and code generation exceptions are faster in the regular path while error codes are faster in the error path. Would it be possible and a good idea to have a language feature that allows some exceptions to use error code code generation.Yes, this has been discussed quite heavily in the past. It is both possible and a good idea, but it won't happen. This is quite typical for possible and good ideas around here... :-)
Jul 10 2016
On 7/10/2016 10:03 AM, Ola Fosheim Grøstad wrote:Yes, this has been discussed quite heavily in the past. It is both possible and a good idea, but it won't happen. This is quite typical for possible and good ideas around here... :-)When has D ever done anything right in your eyes? Just curious!
Jul 10 2016
On Monday, 11 July 2016 at 04:27:35 UTC, Walter Bright wrote:On 7/10/2016 10:03 AM, Ola Fosheim Grøstad wrote:The original plan, to redo C++ by creating a simpler formulation of the same programming model was a good plan. Inheriting many of the same problems as C++ and adding a slew of new ones was not the best move. In the case of exceptions you could've done better as you could generate meta-information that go beyond the dumb C++ manual include-file + basic linkage model. No need for D exceptions to choose the slow C++ exception handling version. You made D incompatible with C++, yet is trying too hard to make it a little bit compatible with it. I think you should make a choice, either make D fully compatible or cut all ties. Modern C++ is 80% header files and templates, linkage does not get you much compatibility these days.Yes, this has been discussed quite heavily in the past. It is both possible and a good idea, but it won't happen. This is quite typical for possible and good ideas around here... :-)When has D ever done anything right in your eyes? Just curious!
Jul 10 2016
On 7/10/2016 10:21 PM, Ola Fosheim Grøstad wrote:On Monday, 11 July 2016 at 04:27:35 UTC, Walter Bright wrote:So what's stopping you from using Scheme?When has D ever done anything right in your eyes? Just curious![ ... more complaints about D ... ]
Jul 11 2016
On Monday, 11 July 2016 at 13:20:50 UTC, Walter Bright wrote:On 7/10/2016 10:21 PM, Ola Fosheim Grøstad wrote:Nothing is stopping me from using Lisp where appropriate. Why are you asking?On Monday, 11 July 2016 at 04:27:35 UTC, Walter Bright wrote:So what's stopping you from using Scheme?When has D ever done anything right in your eyes? Just curious![ ... more complaints about D ... ]
Jul 11 2016
On Sunday, 10 July 2016 at 03:02:31 UTC, Superstar64 wrote:In terms of performance and code generation exceptions are faster in the regular path while error codes are faster in the error path. Would it be possible and a good idea to have a language feature that allows some exceptions to use error code code generation.Personally, I don't understand the need for exceptions at all. Usually, only a calling context can fix the error and continue execution of the program. If exception caught by a top level handler, all it can do is just a crash. Moreover, with exceptions, you need to wrap every piece of code with ugly "try/catch". A plain check of the return code is much better. Sometimes you can't return something adequate (when an index is out of range or container is empty). These cases are programmer's errors and assert is more than enough.
Jul 10 2016
On Sunday, 10 July 2016 at 17:19:31 UTC, phant0m wrote:Personally, I don't understand the need for exceptions at all. Usually, only a calling context can fix the error and continue execution of the program. If exception caught by a top level handler, all it can do is just a crash. Moreover, with exceptions, you need to wrap every piece of code with ugly "try/catch".No, not if you use RAII. In a web server it is quite useful to just let uncaught exceptions result in a http status and unwind transactions automatically without having to put all kinds of error checks in the core logic of the program.
Jul 10 2016
On Sun, 10 Jul 2016 17:19:31 +0000, phant0m wrote:Usually, only a calling context can fix the error and continue execution of the program. If exception caught by a top level handler, all it can do is just a crash.We separate execution into tasks (which could be messages in SQS, or RPCs with a REST interface, or executing a bit of AI script in a game). We observe a failure in a task. Instead of trying to do something intelligent about it inside the implementation of the task, we blindly retry the task with backoff, if appropriate. After a task has failed enough times, it's put into an error queue and the developers are notified.Moreover, with exceptions, you need to wrap every piece of code with ugly "try/catch".Only on a code coverage level. Manual return value checking requires it on a syntactic level. That's why my Go programs are about 20% error checking -- and I *still* have to use try/catch (defer/recover, whatever, it's the same thing).
Jul 10 2016
On Sunday, 10 July 2016 at 03:02:31 UTC, Superstar64 wrote:In terms of performance and code generation exceptions are faster in the regular path while error codes are faster in the error path. Would it be possible and a good idea to have a language feature that allows some exceptions to use error code code generation.I made a DIP for this: https://forum.dlang.org/thread/gkqomdjepixcbtycvepn forum.dlang.org#post-gkqomdjepixcbtycvepn:40forum.dlang.org
Jul 10 2016
On 7/9/16 11:02 PM, Superstar64 wrote:In terms of performance and code generation exceptions are faster in the regular path while error codes are faster in the error path. Would it be possible and a good idea to have a language feature that allows some exceptions to use error code code generation.Swift does exactly this. It doesn't have exceptions, but mimics them by passing a hidden "error" parameter that is filled in if an error occurs. No stack unwinding occurs, just normal returns. This allows them to get around stack unwinding issues with ARC. I don't think this is possible for D to switch to. It would break too much code. You have to instrument your code properly to get this behavior, and it's actually quite unpleasant IMO. -Steve
Jul 11 2016
On 7/9/2016 8:02 PM, Superstar64 wrote:Would it be possible and a good idea to have a language feature that allows some exceptions to use error code code generation.If you want to return an error code, return an error code. No language feature is required.
Jul 11 2016
On Mon, 11 Jul 2016 06:13:00 -0700, Walter Bright wrote:On 7/9/2016 8:02 PM, Superstar64 wrote:I think the intent is to tell the compiler: the error case is very common, so make that case faster at the expense of the happy path. Which is fine in theory, but probably not worth the effort, and it isn't really the greatest usecase for exceptions in general. If errors are so common, you probably want to impress that on the programmer with an explicit status code. just writing a library. You can tell me whether this piece of data is trusted to be correct or not.Would it be possible and a good idea to have a language feature that allows some exceptions to use error code code generation.If you want to return an error code, return an error code. No language feature is required.
Jul 11 2016
On 7/11/2016 9:10 PM, Chris Wright wrote:On Mon, 11 Jul 2016 06:13:00 -0700, Walter Bright wrote:I really have no idea what the benefit is of telling the compiler that.On 7/9/2016 8:02 PM, Superstar64 wrote:I think the intent is to tell the compiler: the error case is very common, so make that case faster at the expense of the happy path.Would it be possible and a good idea to have a language feature that allows some exceptions to use error code code generation.If you want to return an error code, return an error code. No language feature is required.
Jul 11 2016