6 ms·
> Far easier to work with and understand when you dont need to perform a massive disruptive ceremony to handle exceptions. I've been working full time in java f
by throw_m239339 5y ago
> Far easier to work with and understand when you dont need to perform a massive disruptive ceremony to handle exceptions. I've been working full time in java for the past 4 years and basically no one handles exceptions because its so cumbersome and bad to read. Not so in Go. Go does it better.
No Go doesn't do it better, Go just doesn't give you the choice, from a convention perspective. You have a discipline issue with Java, it is not an issue in the language itself, it's with you and your team.
Ironically I've seen a few Go libs and project trying to re-invent optional types due to the verbosity of Go errors, just like people were trying to roll their own generics with interface {} or code generation before they were added to the core. It's a demonstration that some developers don't like the status quo.
- philosopher1234 5y ago> No Go doesn't do it better, Go just doesn't give you the choice, from a convention perspective. You have a discipline issue with Java, it is not an issue in the language itself, it's with you and your team. Its my entire company, and its with the open source ecosystem. Its naive to think that language constructs dont influence dev's decisions. You need to make it easy to do the right thing, not hard, and go makes it easy, which java fails at.
- throw_m239339 5y ago> Its my entire company, and its with the open source ecosystem. Its naive to think that language constructs dont influence dev's decisions. You need to make it easy to do the right thing, not hard, and go makes it easy, which java fails at. Go makes it pretty easy to ignore errors, it's even worse than Java. An uncaught managed exception will not compile, and an uncaught unmanaged exception might terminate your program. _ := YieldsAnError() will will never terminate your program. Go makes it pretty easier to do the wrong thing.
- philosopher1234 5y agoYou're arguing a technicality, which is a waste of time. We should focus on reality, not imaginary theoretical issues. In reality, that never happens. And people even develop linters (frankly unnecessary) to guarantee it, if you're really paranoid. This is a social problem, influenced by language design. You need to be thinking about the way humans actually behave in practice, not how they theoretically might behave. In practice people do not accidentally skip errors in Go. In practice people do not handle errors at all in Java. This is the responsibility of the respective cultures and language designs.
- throw_m239339 5y ago> You're arguing a technicality, which is a waste of time. We should focus on reality, not imaginary theoretical issues. In reality, that never happens. And people even develop linters (frankly unnecessary) to guarantee it, if you're really paranoid. Because you aren't? you're projecting. > This is a social problem, influenced by language design. You need to be thinking about the way humans actually behave in practice, not how they theoretically might behave. Sure, your problem with Java is also a social issue that has nothing to do with the language. > In practice people do not accidentally skip errors in Go. In practice people do not handle errors at all in Java. This is the responsibility of the respective cultures and language designs. This isn't Java's "culture" to not handle errors at all. Go's conventions imposed in its std libs are certainly not a superior model by any measure as I previously showed. Edit: Answer to your follow up since HN ratelimits flamewars > This is java's culture, and I assert it from experience. It is a result of the language design (and communiques from language authorities). Your appeal to authority is a logical fallacy, you have never demonstrated that it is Java culture. I say it isn't Java culture the same way you establish an unfounded claim. > You only showed that it was possible to misbehave in Go, which is totally uninteresting. You have failed to show that your theoretical problem is a practical problem. This is a perfectionist argument. You don't get to say what argument is deemed interest and which isn't in a discussion. Ignoring Go errors is as much as a practical problem that not handling Java exceptions. The difference being that Java does force the developer to catch managed exceptions, Go doesn't care, it's purely a convention. A language construct to deal with errors baked into a language is in theory and practically superior to random conventions established by a vendor. PERIOD. Whatever experience you had with Java isn't representative of Java's culture at all.
- Mawr 5y ago> An uncaught managed exception will not compile, and an uncaught unmanaged exception might terminate your program. While it's nice that uncaught exceptions stop the program from continuing with invalid state, it'd be strictly better to not have them in the first place. That's what languages with explicit error returns provide - can't have uncaught errors if you're forced to explicitly deal with every possible error. The resulting software is way more robust that way. > _ := YieldsAnError() This is a deliberate decision to ignore the error - the programmer needed to explicitly type this out. As such, it's not a problem at all. Even if it was, writing a linter to detect it would be trivial. The real issue with Go's error handling is that you are allowed to implicitly ignore errors in certain cases. Most of them are caught by linters, but some edge cases remain and not compiling is better than needing a linter in the first place.
- throw_m239339 5y ago> This is a deliberate decision to ignore the error - the programmer needed to explicitly type this out. As such, it's not a problem at all. Even if it was, writing a linter to detect it would be trivial. So is not handling Java exceptions is deliberate, and again, Java forces you to handle managed exceptions. > While it's nice that uncaught exceptions stop the program from continuing with invalid state, it'd be strictly better to not have them in the first place. That's what languages with explicit error returns provide - can't have uncaught errors if you're forced to explicitly deal with every possible error. The resulting software is way more robust that way. Errors as value in Go are purely a convention, nothing precludes you from doing the exact same thing in Java, or JavaScript or any other possible language that has exceptions. Furthermore, Go has (stupid) exceptions, it's called panics.
- Mawr 5y ago> So is not handling Java exceptions is deliberate That's the thing, there's no visible difference between a deliberately ignored exception and a purposefully ignored one. The code looks exactly the same: foo() Did I purposefully ignore the exception or not? Can `foo()` even throw an exception? There's no way to know. Once you've programmed with explicit error returns, coming back to exceptions is unnerving. Anything may or may not throw at any time and there's no way to know. > Java forces you to handle managed exceptions. I'm referring to the far more common unchecked exceptions. Java's checked exceptions are a whole another bag of demons I don't want to get into right now. > Errors as value in Go are purely a convention, nothing precludes you from doing the exact same thing in Java, or JavaScript or any other possible language that has exceptions. Thing is, conventions matter. A lot. The proof is in the pudding: - what's the ratio of exception-based Java code to error-based Java code? - what's the ratio of error-based Go code to exception-based Go code? Somehow both ratios end up close to 100%, despite neither language forcing their users to use a specific error handling method. That's because there's space between forcing something and completely ignoring it. I often call it "nudging". Languages often do, and should, nudge their programmers into certain ways of programming that fit their philosophy. > Furthermore, Go has (stupid) exceptions, it's called panics. I assume by "stupid" you mean that panics are underfeatured compared to "real" exceptions. That's intended, you're not supposed to catch panics in the first place. They're only there to address runtime issues that are almost always unrecoverable: running out of memory, out-of-bounds array access, regex compilation failure, etc.
- azth 5y agoThe right thing is to automatically maintain error context (e.g. stack traces) which golang fails at. Furthermore, the vast majority of the time you will have a top level handler that will log the error anyway. golang is just introducing boilerplate for the sake of it, with none of the upsides. Not to mention it also makes it easy to accidentally ignore or overwrite errors, I've seen several instance of that happening over several years of working in golang. Something that would never have happened in an exception based language.
- morelisp 5y ago> Something that would never have happened in an exception based language. Please, over-swallowed exceptions happen all the damn time. Same shit different day. A really common Java problem: T x = foo(); return x.bar(); Now foo() can throw, OK try { T x = foo(); return x.bar(); } catch (Something exc) { return quux(); } You just ate anything from bar(). Instead you gotta do T x; try { x = foo(); } catch (Something exc) { return quux(); } return x.bar(); Which is longer and now your happy-path logic is noised up even worse than most Go handling.
- smw 5y agoOnly with checked exceptions, which I think most of java has made an anti-pattern now?
- morelisp 5y agoNo, it's got nothing to do with checked exceptions. It's from not wanting all the error-handling noise between the two steps of your happy-path logic. And at least in extant Java code and many Java programmers I interview, it's not considered an anti-pattern (but I agree it should be).
- azth 5y agoIt's quite trivial to write a generic function that handles a particular exception else returns a default value, which addresses the above scenario. final var x = getOrDefault(C::foo, Something.class, quux()); return x.bar(); And now with pattern matching in Java, it's trivial to write something similar to Rust's/Scala's `Result<T, E>`/`Try<T>` types and be explicit about all exceptions. I haven't compiled the following, but it's along the lines of: final var x = switch (foo()) { case Ok(var r) -> r; case Error e -> quux(); } return x.bar();
- deleted 5y ago[deleted]
- randomdata 5y ago> Go just doesn't give you the choice The encoding/json package in the Go standard library uses exceptions for error handling. You absolutely have a choice, but it's a choice you're not likely to want to make because exceptions are named exceptions for good reason: It's for exceptions, not errors. Those are very different things. But sometimes the trade-offs of overloading something beyond its intent is worth it. In those cases do it. Balancing trade-offs is what engineering is all about.
- Mawr 5y ago> You have a discipline issue with Java, it is not an issue in the language itself, it's with you and your team. Only if you consider the "language" to be only the language itself, i.e. syntax + semantics. When people refer to a "programming language", they almost always mean the whole package, i.e. the language itself, the community, package ecosystem, tooling, conventions, etc. If there is widespread usage of an incorrect pattern, then it is the failure of the language for not addressing it. For example, C's lack of package/build management. The experiences with exception-based languages others in this thread brought up mirror my own. No thinking about error handling whatsoever, empty `catch` blocks, dumping stacktraces in lieu of error messages, etc. Needing discipline to prevent those is exactly the problem. The language is what should guide you towards a better way, in this case explicitly returning errors.
- throw_m239339 5y ago> Only if you consider the "language" to be only the language itself, i.e. syntax + semantics. When people refer to a "programming language", they almost always mean the whole package, i.e. the language itself, the community, package ecosystem, tooling, conventions, etc. You're making a lot of assumptions based on absolutely no factual data, only your alleged experience. I can dismiss all your arguments easily as anecdotal. As I said earlier Go suffers from having a bad exception system itself (panics/recover) and on the top of that go makes it a breeze to ignore errors: _ := YieldError() You're basically claiming that teams are magically more disciplined just because they use Go. That's of course complete bullshit. An undisciplined team will ignore errors and exceptions the same way. There is nothing in Go that compels anybody to handle errors, just like there is nothing in Java that compels anybody to ignore exceptions. Go errors are purely a convention, Go doesn't have anything in its syntax that forces error as value, it's just what the std library uses. So when talking about Go errors, they are purely talking about a convention, with absolutely no syntax to compel people to follow or enforce that convention. It requires thus even more discipline. Do you really believe your undisciplined programmers that ignored Java exceptions because it's verbose to deal with them are going to magically adopt an even more verbose paradigm? Of course not.