digitalmars.D - Possibility of adopting Rust's Error Handling?
- mee6 (26/26) Mar 31 2022 Rust's error handling is pretty good, I think they've proved the
- user1234 (4/31) Mar 31 2022 [safe navigation]:
- Petar Kirov [ZombineDev] (5/44) Mar 31 2022 Why not for both? `.?` and `??` could be overloadable operators
- mee6 (3/42) Mar 31 2022 That is Rust's equivalent.
- user1234 (3/49) Apr 01 2022 yeah, nice. Everyone needs to see that and think twice.
- IGotD- (29/56) Mar 31 2022 There is a lot of influences from Rust right now but I think we
- H. S. Teoh (15/22) Mar 31 2022 +1.
- Alexandru Ermicioi (10/21) Apr 01 2022 Just wondering, would it be possible to use lubunwind, only in
- H. S. Teoh (8/18) Apr 01 2022 [...]
- mee6 (12/39) Mar 31 2022 Personally I think that's one of the reasons to not use it.
- Paulo Pinto (9/11) Mar 31 2022 It has some warts still, that is why packages like these exist,
- mee6 (7/18) Apr 01 2022 Yes it seems they don't want to commit on those extensions. They
- mesni (6/11) Apr 01 2022 With an already existing Nullable it looks like this:
- mee6 (4/17) Apr 02 2022 You don't get the error of why it is null to begin with, and it
- ryuukk_ (12/12) Apr 02 2022 In my opinion Rust error handling is one of the worst
- mesni (25/52) Apr 01 2022 Moreover, here is an interesting trick
Rust's error handling is pretty good, I think they've proved the use of Result!(T, E). I was just always getting informative messages from the get go. I think there's a nogc exception DIP in the works but I think this way of handling errors is better. I won't go too much into detail of rust as this website does a good job of going over it. https://doc.rust-lang.org/book/ch09-00-error-handling.html Anyways this could be adopted instead of trying to get nogc exceptions working. Rust uses exceptions but only for panic!() Which terminates the application. All it does is rewind the stack to see all the function calls for debugging pretty much. I also think it works with chaining functions as that's what Rust does a lot too. They have a `?` operator that does basically this boiler plate code. ```d auto result = expr; if (result.isErr()) return result; ``` D could implement this fairly easily and without much intrusion, but it would add a lot of value to be able to do something like: ```rust auto value = chain()?.funcs()?; ``` While being nogc and without using exceptions. Other than for panics.
Mar 31 2022
On Thursday, 31 March 2022 at 21:21:04 UTC, mee6 wrote:Rust's error handling is pretty good, I think they've proved the use of Result!(T, E). I was just always getting informative messages from the get go. I think there's a nogc exception DIP in the works but I think this way of handling errors is better. I won't go too much into detail of rust as this website does a good job of going over it. https://doc.rust-lang.org/book/ch09-00-error-handling.html Anyways this could be adopted instead of trying to get nogc exceptions working. Rust uses exceptions but only for panic!() Which terminates the application. All it does is rewind the stack to see all the function calls for debugging pretty much. I also think it works with chaining functions as that's what Rust does a lot too. They have a `?` operator that does basically this boiler plate code. ```d auto result = expr; if (result.isErr()) return result; ``` D could implement this fairly easily and without much intrusion, but it would add a lot of value to be able to do something like: ```rust auto value = chain()?.funcs()?; ```yikes, I'd prefer if D could use `?` for [safe navigation].While being nogc and without using exceptions. Other than for panics.[safe navigation]: https://en.wikipedia.org/wiki/Safe_navigation_operator
Mar 31 2022
On Thursday, 31 March 2022 at 21:35:00 UTC, user1234 wrote:On Thursday, 31 March 2022 at 21:21:04 UTC, mee6 wrote:Why not for both? `.?` and `??` could be overloadable operators like `opDot`, which when applied to pointers and class references will behave like they do in other languages, while structs could overload them to implement behavior like Rust's `Result` type.Rust's error handling is pretty good, I think they've proved the use of Result!(T, E). I was just always getting informative messages from the get go. I think there's a nogc exception DIP in the works but I think this way of handling errors is better. I won't go too much into detail of rust as this website does a good job of going over it. https://doc.rust-lang.org/book/ch09-00-error-handling.html Anyways this could be adopted instead of trying to get nogc exceptions working. Rust uses exceptions but only for panic!() Which terminates the application. All it does is rewind the stack to see all the function calls for debugging pretty much. I also think it works with chaining functions as that's what Rust does a lot too. They have a `?` operator that does basically this boiler plate code. ```d auto result = expr; if (result.isErr()) return result; ``` D could implement this fairly easily and without much intrusion, but it would add a lot of value to be able to do something like: ```rust auto value = chain()?.funcs()?; ```yikes, I'd prefer if D could use `?` for [safe navigation].While being nogc and without using exceptions. Other than for panics.[safe navigation]: https://en.wikipedia.org/wiki/Safe_navigation_operator
Mar 31 2022
On Thursday, 31 March 2022 at 21:35:00 UTC, user1234 wrote:On Thursday, 31 March 2022 at 21:21:04 UTC, mee6 wrote:That is Rust's equivalent. https://en.m.wikipedia.org/wiki/Safe_navigation_operator#RustRust's error handling is pretty good, I think they've proved the use of Result!(T, E). I was just always getting informative messages from the get go. I think there's a nogc exception DIP in the works but I think this way of handling errors is better. I won't go too much into detail of rust as this website does a good job of going over it. https://doc.rust-lang.org/book/ch09-00-error-handling.html Anyways this could be adopted instead of trying to get nogc exceptions working. Rust uses exceptions but only for panic!() Which terminates the application. All it does is rewind the stack to see all the function calls for debugging pretty much. I also think it works with chaining functions as that's what Rust does a lot too. They have a `?` operator that does basically this boiler plate code. ```d auto result = expr; if (result.isErr()) return result; ``` D could implement this fairly easily and without much intrusion, but it would add a lot of value to be able to do something like: ```rust auto value = chain()?.funcs()?; ```yikes, I'd prefer if D could use `?` for [safe navigation].While being nogc and without using exceptions. Other than for panics.[safe navigation]: https://en.wikipedia.org/wiki/Safe_navigation_operator
Mar 31 2022
On Thursday, 31 March 2022 at 22:05:30 UTC, mee6 wrote:On Thursday, 31 March 2022 at 21:35:00 UTC, user1234 wrote:yeah, nice. Everyone needs to see that and think twice. Is Rust awefull afterall ?On Thursday, 31 March 2022 at 21:21:04 UTC, mee6 wrote:That is Rust's equivalent. https://en.m.wikipedia.org/wiki/Safe_navigation_operator#RustRust's error handling is pretty good, I think they've proved the use of Result!(T, E). I was just always getting informative messages from the get go. I think there's a nogc exception DIP in the works but I think this way of handling errors is better. I won't go too much into detail of rust as this website does a good job of going over it. https://doc.rust-lang.org/book/ch09-00-error-handling.html Anyways this could be adopted instead of trying to get nogc exceptions working. Rust uses exceptions but only for panic!() Which terminates the application. All it does is rewind the stack to see all the function calls for debugging pretty much. I also think it works with chaining functions as that's what Rust does a lot too. They have a `?` operator that does basically this boiler plate code. ```d auto result = expr; if (result.isErr()) return result; ``` D could implement this fairly easily and without much intrusion, but it would add a lot of value to be able to do something like: ```rust auto value = chain()?.funcs()?; ```yikes, I'd prefer if D could use `?` for [safe navigation].While being nogc and without using exceptions. Other than for panics.[safe navigation]: https://en.wikipedia.org/wiki/Safe_navigation_operator
Apr 01 2022
On Thursday, 31 March 2022 at 21:21:04 UTC, mee6 wrote:Rust's error handling is pretty good, I think they've proved the use of Result!(T, E). I was just always getting informative messages from the get go. I think there's a nogc exception DIP in the works but I think this way of handling errors is better. I won't go too much into detail of rust as this website does a good job of going over it. https://doc.rust-lang.org/book/ch09-00-error-handling.html Anyways this could be adopted instead of trying to get nogc exceptions working. Rust uses exceptions but only for panic!() Which terminates the application. All it does is rewind the stack to see all the function calls for debugging pretty much. I also think it works with chaining functions as that's what Rust does a lot too. They have a `?` operator that does basically this boiler plate code. ```d auto result = expr; if (result.isErr()) return result; ``` D could implement this fairly easily and without much intrusion, but it would add a lot of value to be able to do something like: ```rust auto value = chain()?.funcs()?; ``` While being nogc and without using exceptions. Other than for panics.There is a lot of influences from Rust right now but I think we should be cautious adopting its features because I see more and more that many of the features don't age well. What is Rust error handling? Rust error handling is basically a tagged enum return type. Essentially it is a return value with some extra language built in features (like the ? mentioned). Problem with the Rust error handling is that you must use the same type for the entire call chain for it to work. Otherwise you must convert the error type or use a generic trait which dynamically allocated. Essentially you have the same problems as you would with return values. Its just an inferior error handling method compared to exceptions other than it might have better for performance. Versatility always comes at a cost. If you compare this with exceptions, they are much more versatile and the types can be infinitely expanded without even converting or alter an existing interface. Exceptions in D use TypeInfo (or RTTI in C++) in order to determine the error type. An advantage is that it uses polymorphism so that you can selectively choose the level which errors you want to catch. D has made exceptions even more convenient by adding scope guard so it is really a part of the language. I think that exceptions are superior to return values for the programmer. However there are performance bottlenecks. Instead D should focus on how to improve its exceptions, like looking if value exceptions could be beneficial, unnecessary locking, if they can be stored temporarily on stack instead of heap, how they can better work with the optimizer, include TypeInfo in better C so that exceptions work there.
Mar 31 2022
On Thu, Mar 31, 2022 at 09:46:53PM +0000, IGotD- via Digitalmars-d wrote: [...]I think that exceptions are superior to return values for the programmer.+1.However there are performance bottlenecks. Instead D should focus on how to improve its exceptions, like looking if value exceptions could be beneficial, unnecessary locking, if they can be stored temporarily on stack instead of heap, how they can better work with the optimizer, include TypeInfo in better C so that exceptions work there.AIUI, D used to have its own implementation of exceptions that was more performant than libunwind. Sadly, that got junked in the name of C++ compatibility, so now we're stuck with libunwind along with all of its downfalls. In theory, if we're willing to accept ABI changes, we could replace the current libunwind-based implementation with a register-based status to indicate when an exception is thrown, and emit explicit branches for that. Then it would be the equivalent of error-code-based handling, except without the code uglification and the type constraints. T -- Computers are like a jungle: they have monitor lizards, rams, mice, c-moss, binary trees... and bugs.
Mar 31 2022
On Thursday, 31 March 2022 at 22:00:17 UTC, H. S. Teoh wrote:AIUI, D used to have its own implementation of exceptions that was more performant than libunwind. Sadly, that got junked in the name of C++ compatibility, so now we're stuck with libunwind along with all of its downfalls. In theory, if we're willing to accept ABI changes, we could replace the current libunwind-based implementation with a register-based status to indicate when an exception is thrown, and emit explicit branches for that. Then it would be the equivalent of error-code-based handling, except without the code uglification and the type constraints. TJust wondering, would it be possible to use lubunwind, only in extern c++ declarations? I.e. we'd have own exception handling in D code, and C++ compliant exceptions in extern C++ one? This would mean that when d code interacts with c++ it will get translated into respective mechanism, from c++ if it is from c++ code called by D code, and into c++ one if it is from extern c++ d code that is called by c++ code. Alexandru
Apr 01 2022
On Fri, Apr 01, 2022 at 09:41:09AM +0000, Alexandru Ermicioi via Digitalmars-d wrote: [...]Just wondering, would it be possible to use lubunwind, only in extern c++ declarations? I.e. we'd have own exception handling in D code, and C++ compliant exceptions in extern C++ one? This would mean that when d code interacts with c++ it will get translated into respective mechanism, from c++ if it is from c++ code called by D code, and into c++ one if it is from extern c++ d code that is called by c++ code.[...] That's what I'd propose. But Walter seems dead set against exceptions in general, so I dunno whether this will ever actually happen. T -- Lottery: tax on the stupid. -- Slashdotter
Apr 01 2022
On Thursday, 31 March 2022 at 21:46:53 UTC, IGotD- wrote:On Thursday, 31 March 2022 at 21:21:04 UTC, mee6 wrote:Personally I think that's one of the reasons to not use it. Errors that are recoverable are finite. There's no good way to see exactly what it will throw. With return value handlingly you know exactly what you are getting. You could make it more generic or at multiple types. Errors shouldn't happen often and yes that would have to heap allocate but those are tradeoffs that can be looked over.[...]There is a lot of influences from Rust right now but I think we should be cautious adopting its features because I see more and more that many of the features don't age well. What is Rust error handling? Rust error handling is basically a tagged enum return type. Essentially it is a return value with some extra language built in features (like the ? mentioned). Problem with the Rust error handling is that you must use the same type for the entire call chain for it to work. Otherwise you must convert the error type or use a generic trait which dynamically allocated. Essentially you have the same problems as you would with return values. Its just an inferior error handling method compared to exceptions other than it might have better for performance. Versatility always comes at a cost. If you compare this with exceptions, they are much more versatile and the types can be infinitely expanded without even converting or alter an existing interface.D has made exceptions even more convenient by adding scope guard so it is really a part of the language. I think that exceptions are superior to return values for the programmer. However there are performance bottlenecks. Instead D should focus on how to improve its exceptions, like looking if value exceptions could be beneficial, unnecessary locking, if they can be stored temporarily on stack instead of heap, how they can better work with the optimizer, include TypeInfo in better C so that exceptions work there.Both can exist together, you can have a library implementation of Result. The feature for it is aldo a small convince but ultimately isn't required to get the benefits of result value error handling.
Mar 31 2022
On Thursday, 31 March 2022 at 21:21:04 UTC, mee6 wrote:Rust's error handling is pretty good, I think they've proved the use of Result!(T, E)....It has some warts still, that is why packages like these exist, https://docs.rs/thiserror/latest/thiserror/ https://docs.rs/anyhow/latest/anyhow/ To work around the boilerplate and lack of support in standard library when combining errors from different libraries. Rust still suffers from a npm like approach to stuff that should be part of the standard library for basic stuff, error definition, async runtimes, serialization,...
Mar 31 2022
On Friday, 1 April 2022 at 06:17:53 UTC, Paulo Pinto wrote:On Thursday, 31 March 2022 at 21:21:04 UTC, mee6 wrote:Yes it seems they don't want to commit on those extensions. They seem to not want to define what an error is which leads to that problem. It can be avoided by including those things in the implementation details. C++ has an expect struct in the pipeline but it doesn't define what an error is either, nor how to handle multiple error types. That would need to be worked on as well.Rust's error handling is pretty good, I think they've proved the use of Result!(T, E)....It has some warts still, that is why packages like these exist, https://docs.rs/thiserror/latest/thiserror/ https://docs.rs/anyhow/latest/anyhow/ To work around the boilerplate and lack of support in standard library when combining errors from different libraries. Rust still suffers from a npm like approach to stuff that should be part of the standard library for basic stuff, error definition, async runtimes, serialization,...
Apr 01 2022
On Thursday, 31 March 2022 at 21:21:04 UTC, mee6 wrote:Rust's error handling is pretty good, I think they've proved the use of Result!(T, E). I was just always getting informative messages from the get go. I think there's a nogc exception DIP in the works but I think this way of handling errors is better. [...]With an already existing Nullable it looks like this: ```d auto value = chain().get.funcs().get; ``` I don't see much difference
Apr 01 2022
On Saturday, 2 April 2022 at 02:29:16 UTC, mesni wrote:On Thursday, 31 March 2022 at 21:21:04 UTC, mee6 wrote:You don't get the error of why it is null to begin with, and it doesn't forward errors. It is quite different even if the syntax is similar.Rust's error handling is pretty good, I think they've proved the use of Result!(T, E). I was just always getting informative messages from the get go. I think there's a nogc exception DIP in the works but I think this way of handling errors is better. [...]With an already existing Nullable it looks like this: ```d auto value = chain().get.funcs().get; ``` I don't see much difference
Apr 02 2022
In my opinion Rust error handling is one of the worst I much preffer Go/Zig/Odin, my favorite would be Odin's one f, err := os.open(...) if err != os.ERROR_NONE { // handle error } defer os.close(f) // will be executed at the end of the scope Multiple returns is the trick!! simple, easy to read and handle, i can understand if one prefer exception sicne they bubble up, even though i think it encourages a lazy design of APIs, for that, then Zig's one will suits you better, since it's more strict about that part
Apr 02 2022
On Thursday, 31 March 2022 at 21:21:04 UTC, mee6 wrote:Rust's error handling is pretty good, I think they've proved the use of Result!(T, E). I was just always getting informative messages from the get go. I think there's a nogc exception DIP in the works but I think this way of handling errors is better. I won't go too much into detail of rust as this website does a good job of going over it. https://doc.rust-lang.org/book/ch09-00-error-handling.html Anyways this could be adopted instead of trying to get nogc exceptions working. Rust uses exceptions but only for panic!() Which terminates the application. All it does is rewind the stack to see all the function calls for debugging pretty much. I also think it works with chaining functions as that's what Rust does a lot too. They have a `?` operator that does basically this boiler plate code. ```d auto result = expr; if (result.isErr()) return result; ``` D could implement this fairly easily and without much intrusion, but it would add a lot of value to be able to do something like: ```rust auto value = chain()?.funcs()?; ``` While being nogc and without using exceptions. Other than for panics.Moreover, here is an interesting trick ```d import std.stdio; import std.typecons; import std.exception; template ErrorGet(alias Func){ ref auto getn(T)(ref T n){ if(n.isNull) Func(0); return n.get(); } } alias PanicGet = ErrorGet!((a){assert(a);}); alias ThrowGet = ErrorGet!(enforce); void main(){ Nullable!int a; a = 8; with(PanicGet){ a.getn.writeln; } with(ThrowGet){ a.getn.writeln; } } ```
Apr 01 2022