"Which program is easier to read?" For me it was the second. Am I the only one ?
Away from Exceptions: Errors as Values
21–30 of 145 posts
Re: Away from Exceptions: Errors as Values
#22No, I don't want to wrap every single statement of my program in its own if-block, thank you very much.
like Railway Oriented Programming
https://www.youtube.com/watch?v=45yk2nuRjj8
I believe that almost every thing should return Result, because almost everything can fail and compiler should scream when you do not handle those fail pathes.
That makes me believe that C#'s "FirstOrDefault" for value types sucks, because you're never sure whether the "Default" comes due to lack of value or because the found value is actually the same as default
e.g
var list = new List {1,2,3};
var found = list.FirstOrDefault(x => x found = 0 (default)
meanwhile 0 may be valid value! so we aren't sure whether it is error or an actual value
and we have to perform e.g casts to `int?` or stuff to detect that.
using Result gives very precise information
Re: Away from Exceptions: Errors as Values
#23It's good to see so much focus on errors. They are essential when trying to build resilient systems. But our approaches are still very immature. First, to make it clear, this article appropriately points out that exceptions are still necessary and relevant. I disagree with some of the use-cases given, but it's important to recognize that exceptions should still exist in programming languages. Joe Duffy's article abou…
Exactly. The control flow. Both errors and asynchronous programming share the quality that they don't go well with our call/return based programming model(s). You have to return something, but you either don't have anything (error) or don't have something yet (async).
A great solution to this is to use dataflow. This decouples the logic, which is encoded in the dataflow, from the control flow, which just serves to drive the dataflow, and thus negotiable.
For async, it is synchrony-agnostic, which is nice, because it solves, or rather sidesteps, the "function colouring" problem. For errors, it allows you to keep error handling out of the happy path without needing exceptions.
Re: Away from Exceptions: Errors as Values
#24Nonsense.
Re: Away from Exceptions: Errors as Values
#25No, I don't want to wrap every single statement of my program in its own if-block, thank you very much.
Re: Away from Exceptions: Errors as Values
#26Personally, i really like having multiple return values, since being able to give a function multiple inputs but only being able to return a single thing always felt weird - if your require any metadata in a language like Java, then you'd have to come up with wrapper objects and so on. That said, i really dislike the following from the article: if (error) { // you can handle the error as you see fit // you can add mo…
> Personally, i really like having multiple return values, since being able to give a function multiple inputs but only being able to return a single thing always felt weird - if your require any metadata in a language like Java, then you'd have to come up with wrapper objects and so on. MRV is nice and useful, and “error as value” languages usually have ways to return multiple values (usually in the form of tuple),…
I actually agree with Rust's choice here. You, the programmer, know whether some particular error is something you can cope with or not and it's appropriate to panic in the latter case. Where you draw the line is up to you, in a ten line demo chances are "the file doesn't exist" is a panic, in your operating system kernel maybe even "the RAM module with that data in it physically went away" is just a condition to cope with and carry on.
My litmus test here is Authenticated Encryption. The obvious and easy design of the decrypt() method for your encryption should make it impossible for a merely careless or incompetent programmer to process an unauthenticated decryption of the ciphertext. This makes most sense if you have an AE cipher mode, but it was already the correct design for both MAC-then-Encrypt or Encrypt-then-MAC years ago, and yet it's common to see APIs that didn't behave this way especially on languages with poor error handling.
In languages with a Sum type Result like Rust, obviously the plaintext is only inside the Ok Result, and so if the Result is an Err you don't have a plaintext to mistakenly process.
In languages with a Product type or Tuple returns like Go, it's still easy to do this correctly, but now it's also easy to mistakenly fill out the plaintext in the error case, and your user may never check the error. Dangerous implementations can thus happen by mistake.
In languages with C-style simple returns, it's hard to do this properly, you're likely using an out-buffer pointer as a parameter, and your user might not check the error return. You need to explicitly clear or poison the buffer on error and even then you're not guaranteed to avoid trouble.
In languages with Exceptions, the good news is that the processing of the bogus plaintext probably doesn't happen, but the bad news is that you're likely now in a poorly tested codepath that isn't otherwise taken, maybe far from the proximate cause of the trouble. Or worse, your user wraps your annoying Exception-triggering decrypt method and repeats one of the above mistakes since they don't have better options.
Re: Away from Exceptions: Errors as Values
#27Funny how exception were invented because handling errors as values was considered to be tedious. And now, more and more languages are going backward.
Re: Away from Exceptions: Errors as Values
#28> Programming with exceptions is difficult and inelegant. Learn how to handle errors better by representing them as values. Funny how exception were invented because handling errors as values was considered to be tedious. And now, more and more languages are going backward.
-1, 0, 1 and other obscure things
and using proper types like
Result
Re: Away from Exceptions: Errors as Values
#29No, I don't want to wrap every single statement of my program in its own if-block, thank you very much.
Have you considered using patterns that help dealing with that? like Railway Oriented Programming https://www.youtube.com/watch?v=45yk2nuRjj8 I believe that almost every thing should return Result , because almost everything can fail and compiler should scream when you do not handle those fail pathes. That makes me believe that C#'s "FirstOrDefault" for value types sucks, because you're never sure whether the "Defaul…
This function is useful when you don't really care whether it's an error or the value. Imagine you're querying the view count of an item of the user. If the user is anonymous, the select might give an empty result, but you only care about showing a number to the user. So 0 is absolutely fine in that case.
If it's important to you whether the item actually exist, you're using the method in the wrong place.
Re: Away from Exceptions: Errors as Values
#30The post links to an "Exception Smells" post that doesn't mention one of my pet peeves: exceptions as control flow. For example, Java's parseInt [1] throws a NumberFormatException if the string can't be parsed. IMHO this is terrible design. As a side note, checked exceptions are terrible design.
I wrote C++ with Google's C++ dialect where exceptions were forbidden. Some chafed under this restriction. It was largely a product of the time (ie more than 20 years ago now when this was established). Still there's debate about whether it's even possible to write exception-safe C++ code. In the very least it's difficult.
So Google C++ uses a value and error union type, open sourced as absl::StatusOr [2]. The nice thing was you couldn't ignore this. The compiler enforced it. If you really wanted to ignore it, it had to be explicit ie:
foo().IgnoreError();
But here's where the author lost me: this chaining coding style he has at the end. To make it "readable" a bunch of functions had to be created. You can't step through that code with a debugger. The error messages may be incomprehensible.I much prefer Rust's or Go's version of this, which is instead imperative.
[1]: https://docs.oracle.com/javase/7/docs/api/java/lang/Integer....