3 ms·
In Java, you'd expect map() to throw, and the type of y to be Vec<string>, in Rust parlance. If one of the conversions failed, you'd expect the stack to unwind
by barrkel 7y ago
In Java, you'd expect map() to throw, and the type of y to be Vec<string>, in Rust parlance. If one of the conversions failed, you'd expect the stack to unwind as the exception propagates, and you'd expect that the use of map() means you're not particularly interested in which item failed, you just want to abort (roll back) on failure. This is the 99.9% use case for exception in Java, or C#, or Delphi; you almost never catch exceptions.
If you're interested in which item failed, ideally you'd be using a method that doesn't throw at all, and instead returns an error condition. I like how C# makes this clear, with Parse and TryParse on Int32. You use Parse when you want unwinding and abort behaviour including stack unwinding, and TryParse when you want to handle errors, and you don't use exceptions for expected errors, since expected errors are not exceptional.
(If the map is lazy, you'd expect the materialization in collect() to throw. But the return type wouldn't change.)
IMO, the kind of code you write on a daily basis is the primary determinant of your preference for error codes vs exceptions. If you need to handle error conditions frequently, you'll prefer error codes, because they're data, like all other data, and you can use the general compositional tools at your disposal to manipulate them. If you handle error conditions exceedingly rarely, and mostly just want to abort, unwind, roll back, go back to the main loop and log them, then exceptions are your friend.
I do not think there is a fundamental superiority either way. I think there are tools for purposes. I do think that Java's checked exceptions are half-baked; they're half-way into the compile time type system in a language whose applications are generally better suited to run time exceptions.
- lmm 7y ago> In Java, you'd expect map() to throw You'd have to use unchecked exceptions to achieve that though. There's no way to propagate the checked exception across that call, because there's no way to make map() generic over exception-or-not in a Java/Rust-like type system. > If you're interested in which item failed, ideally you'd be using a method that doesn't throw at all, and instead returns an error condition. I like how C# makes this clear, with Parse and TryParse on Int32. You use Parse when you want unwinding and abort behaviour including stack unwinding, and TryParse when you want to handle errors, and you don't use exceptions for expected errors, since expected errors are not exceptional. Result gets you that without needing to write two implementations of every method. You call unwrap-or-panic in the cases where error is not expected/handled, and handle it in the cases where you want to handle it.