Comments by "" (@diadetediotedio6918) on "Why I Prefer Exceptions To Errors" video.
-
33
-
10
-
6
-
5
-
4
-
4
-
4
-
4
-
3
-
3
-
3
-
3
-
3
-
3
-
2
-
@isodoubIet
> Of course it's a bad thing. It inhibits code reuse
It really depends on what you are calling "code reuse", I'd need to disagree with you on this one if you don't show some concrete real world examples of this.
> loosens the system modeling as you're now encouraged to report and handle errors even if there's no possibility of such
This is a sign of bad API design and not a problem with having errors as values. If you are returning a "maybe error" from a function then it <maybe> an error, it is a clear decision to make.
> increases coupling between unrelated parts of the code
I mean, not really, you can always flatten errors or discard them easily in an EAV model.
> and can force refactorings of arbitrarily large amounts of code if even one call site is modified.
Again, this is true for any kind of function coloring, including <type systems> and <checked exceptions> (like Java has). A good designed code should be resilient to this kind of problem most of the time.
> You can say "this is a tradeoff I'm willing to make". That is fine. You cannot say this isn't a bad thing.
I absolutely can say it is not a bad thing. It is not a bad thing. See? I don't think function coloring is necessarily bad, thus I would not agree with you upfront this is a bad thing. I think being explicit about what a code does and the side effects that it can trigger is a good thing, an annoying thing sometimes I can concede, but I cannot call it a "bad thing" on itself, only the parts that are actually annoying (and the same goes for when you don't have this kind of coloring and then it blows up in your head because of it, it is a "bad thing", not the lack of coloring itself).
2
-
2
-
2
-
2
-
2
-
2
-
2
-
1
-
1
-
@isodoubIet
You have a problem in understanding, I see.
My claim was: ["Plus, function coloring is required whenever you <use any type system at all>, and it is not a problem because the Rust type system can infer the types for you, so most of the time this is not a concern."], learn to read things entirely instead of nitpicking parts. Function coloring is a defacto thing for any language that has types, including C++. It do not mean that the errors will be part of that function coloring, it just means it <exists> in the language when you are using it, if the point is that <function coloring = bad> this should be a problem for you.
> Also nonsense. If you change the error handling strategy of some function deep in the call stack, you'll end up needing to refactor an arbitrary large amount of code.
Just like if you suddenly need your exceptions to matter more locally you need to refactor an arbitrarily large amount of code to catch them in every possible single call site. It also matters more for me if you are designing your systems so badly this is often necessary, but anyways. And if you use Java for example exceptions can be <function coloring> as they need to be marked in the header of functions (and if you skip them you need to mark your function or convert it to an uncked one). This is just a terrible point in defense of exceptions.
1
-
1
-
1
-
1
-
@s3rit661
I don't think this is "the same argument".
1. Checked exceptions are, in fact, optional in Java, you can quite literally ignore them and turn them into unchecked ones (and many of those that are actually important, like NPEs, are ignorable). Kotlin is a language that runs in JVM and literally ditcched checked exceptions, if this was a concept working in Java I don't think they would go to this route.
2. The Rust thing is about <memory safety>, not about "ensuring you never make mistakes", memory safety is a no-problem in languages like Java and Rust ensures you don't make mistakes with memory with the borrow checker, which is another thing than error checking mechanism. The guarantees you have there are extremely specific as well, it is not "it is impossible to make mistakes", it is "if you use the type-system, if you check your unsafe code with tools like MIRI and do proper tests on it, if you don't circumvent borrow checker rules, them you are in the possible program space where it should be impossible for you to create a memory safety issue in your program". The error as values are a bonus and they work pretty well with this system.
1
-
1
-
1
-
1
-
1
-
1
-
@yyny0
(my message apparently got swizzled, so sending it again)
This is true, yes, but arguably the overhead of doing these checks is minimal if you are constraining yourself to when they actually need to happen. And while it is true that you cannot circumvent this problem when having errors as values (unless you are willing to deal with pointer manipulation, in which case you can pretty much skip the check, but nobody does this), you can also not avoid this if you are trying to make a locality enforced error handling with exceptions (as you will need to have the try-catch everywhere in your code, and you will pay the cost of having the extra code in your function for dealing with the exception just like in the eav case).
It is also arguable if the cost of checking the stack frames that <do> need the cleanup would not outweight the benefits in performance you are claiming it has, but I did not measured this to say, maybe I'm not considering even more factors here like the non-locality of code causing a problem with the predictors in the CPU (or the whole context switching problem that is a pretty massive hit for CPUs, althought I cannot say the cost ammortizes when you don't have many exceptions).
1
-
1
-
1
-
1
-
1
-
1
-
1
-
1
-
1
-
@yyny0
> [ Crates like anyhow? Most libraries do not use that crate, and in fact, the recommendation from anyhow author is to NOT use them for library code. This means that the errors returned from those libraries do NOT have stacktraces, and NO way to recover them. ]
Oh, now I get it. You want to have <libraries stack trace>, not <stacktrace in general>. Well, first: It is indeed possible to get the stacktrace of a program from errors as values, so your statement was wrong. You can move the discussion to the fact that this is more of a problem with libraries, and I would agree, it is a pain in this specific case, but you <cannot say> it <can't be done>, it can. Now, you said this is a problem for <errors as values>, but this is more of a problem for <Rust>. A language crafted around errors as values that have stacktraces opt-in at the consumer level of libraries would literally solve this problem and then your point would be much less interesting, so it is kinda fragile to criticize errors as values in this regard based on the design decisions of Rust.
> [We've had several "fun" multi-hour debug sessions because of that.]
So you are using Rust? What, you just said your service has many exceptions and all in the other comment, or are you talking about a different project or something like that? Also, can you explain me exactly how the lack of stacktraces in specific libraries costed you "several 'fun' multi-hour debug sessions"? I literally never experienced a "multi-hour debug session" because of something like that, and I work on a heck lot of projects, so a more concrete explanation will be good for the mutual understanding part of this discussion.
> [Also, those crates are opt-in, and even some of our own code does not use anyhow, because it makes error handling an absolute pain compared to a plain `enum`s.]
It makes? What??? It literally was made <to make using errors less painful>, given the purpose of this library, why do you find it <an absolute pain> compared to plain enums? You also don't need to use anyhow, see, you can literally easily capture stacktraces in your application by using std::backtrace::capture or force_capture, in the Rust page they even say it is a pretty easy way of gathering the causal chain that lead to the errors, you literally need to implement like 30 lines of code and use it in your whole application if you want to.
1
-
1
-
1
-
@yyny0
> [An error is incorrect by definition, it is NOT a valid representation of your system, in fact, the whole point of returning an error value is to describe invalid program state.]
What I said: ["a perfectly valid representation of a specific part of a system in a given time"], an error IS, in fact, a perfectly <valid> (in a formal sense, and sometimes in business rules) <representation> of a <specific part> of a system in a given time. When you do a login and you type the password wrong, the InvalidPassword <IS>, in fact, a perfectly reasonable and valid <representation> of state in your system (as it should be, it should not panic your software, just exhibit a simple message to the user so he can type the correct password). When you call a method to write to a file, and the file do not exist, receiving a monad where the error is represented as a possibility <IS>, indeed, a perfectly valid way of representing your program state. I just don't know why are you saying this. An error could be defined as a "undesired state given a specific goal intended in a closed system", but not necessarily as an "invalid state" if it is conceived as to be a part of the representation of your possible states. dot.
Proceeding.
> [As for statistics: our production product has ~20k `throw`s across all our (vendored) dependencies (of which ~2k in our own code), and only 130 places where we catch them. Most of those places also immediately retry or restart the entire task.(...)Additionally, 99.9998% of those tasks in the last hour did not return an error, so even if the cost of throwing a single error was 1000x the cost of running an entire task (which it is not), it would still be irrelevant.]
You said "it should never happen", and then you showed me your personal data and said it happens 20k times, I would say this is a damn high number to say it "should never happen". Also, you did not give me any timeframe, not a comparison between different services, giving me one personal example is just anedoctal example. How exactly I'm supposed to work with this and say there are not very statistically representative systems that <do> have an impact with throwing exceptions for everything? This is a pretty specific response.
> [I would consider that "grinding to a halt".]
You consider restarting a program immediately after an error the same as "grinding to a halt"?
1
-
1
-
1
-
1
-
1