Comments by "" (@diadetediotedio6918) on "Why I Prefer Exceptions To Errors" video.

  1. 33
  2. 10
  3. 6
  4. 5
  5. 4
  6. 4
  7. 4
  8. 4
  9. 3
  10. 3
  11. 3
  12. 3
  13. 3
  14. 3
  15. 2
  16.  @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
  17. 2
  18. 2
  19. 2
  20. 2
  21. 2
  22. 2
  23. 1
  24. 1
  25. 1
  26. 1
  27. 1
  28. 1
  29. 1
  30. 1
  31. 1
  32. 1
  33. 1
  34. 1
  35. 1
  36. 1
  37. 1
  38. 1
  39. 1
  40. ​ @isodoubIet  My claim is that throwing exceptions is functionally equivalent to a goto. <Functionally> meaning it functions in a similar fashion (i.e. you are jumping from an arbitrary place in your code to a predefined another place, not only it functions but exceptions are also implemented that way in C++). You cannot also exactly "goto arbirary random places in the code" with non-local gotos (in most languages that have it, at least), you need to add a mark to those places firstly. I used specifically the words "(and can even be used for the same purposes many times)" in my argument, so do you want me to show it? First: ``` #include <iostream> #include <csetjmp> std::jmp_buf jumpBuffer; void second_fn() { std::cout << "in :: [second_fn]" << std::endl; std::longjmp(jumpBuffer, 2); std::cout << "will not happen" << std::endl; } void first_fn() { std::cout << "in :: [first_fn]" << std::endl; second_fn(); std::cout << "will not happen" << std::endl; } int main() { std::cout << "in :: [main]" << std::endl; int ret = setjmp(jumpBuffer); if (ret == 0) { std::cout << "calling :: [first_fn]" << std::endl; first_fn(); } else if (ret == 2) { std::cout << "in :: [main] from -> second_fn with : longjmp" << std::endl; } std::cout << "end" << std::endl; return 0; } ``` Second: ``` #include <iostream> #include <string>; void second_fn() { std::cout << "in :: [second_fn]" << std::endl; throw "ops"; std::cout << "will not happen" << std::endl; } void first_fn() { std::cout << "in :: [first_fn]" << std::endl; second_fn(); std::cout << "will not happen" << std::endl; } int main() { std::cout << "in :: [main]" << std::endl; try { std::cout << "calling :: [first_fn]" << std::endl; first_fn(); } catch(const char*) { std::cout << "in :: [main] from -> second_fn with : exceptions" << std::endl; } std::cout << "end" << std::endl; return 0; } ``` The results: ``` A -> in :: [main] calling :: [first_fn] in :: [first_fn] in :: [second_fn] in :: [main] from -> second_fn with : longjmp end B -> in :: [main] calling :: [first_fn] in :: [first_fn] in :: [second_fn] in :: [main] from -> second_fn with : exceptions end ```
    1
  41. 1
  42. 1
  43. 1
  44. ​ @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
  45. 1
  46. 1
  47. ​ @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
  48. 1
  49. 1
  50. 1
  51. 1