9 ms·
I’m sorry but to me this just looks like Stockholm syndrome all the way. The approach suggested for Go 2 under bargaining is basically a reverse try-catch at b
by josteink 8y ago
I’m sorry but to me this just looks like Stockholm syndrome all the way.
The approach suggested for Go 2 under bargaining is basically a reverse try-catch at best and a Visual Basic “on error goto” at worst.
Even in their own attempt to explain why try catch is bad they effectively admit it serves a common use-case: A common use-case not handled by Go no less.
This lacking also puts the burden on the programmer which will have to manually handle each and every error, by himself, everywhere, one by one.
Even worse are the priorities given in the language: checking for errors is cumbersome, while ignoring errors is easy.
I’m willing to be proven wrong, but my immediate guess is that this in general leads to more buggy code, not less.
- sephware 8y agoWithout taking sides on the issue, these are purposeful trade-offs that the Go team makes. They are trying to avoid bloating the language and making it too difficult for them to add optimizations or other features. And I think they would argue that it makes ignoring errors harder, since you have to intentionally discard the error value when it was given to you, which takes conscious effort, rather than omitting it from the code completely like other languages let you.
- nomel 8y agoI find this perspective curious. Maybe it's the non-web field that I work in, but I've never written a program where I could unintentionally ignore errors and have things go as expected after. What are some cases where errors can be ignored? And if they can be, are these neccesarily some sort of "status" rather than "error"?
- sephware 8y agoIf you're writing a command line utility that tries to load a config file and falls back on defaults if it's not found, you may try to load it and just ignore any error, only caring that it either returns a path if found or null if you should use default values.
- dwaite 8y agoI believe what you are saying is that you can ignore errors if you check or rely on the side effects of an error (such as the result of a function being null on error). One could argue that the side effect is part of the error, and really what you are ignoring are the details of an error (e.g. did the config entry fail to load because the config file wasn't found, because of filesystem permissions, or because the particular configuration key wasn't present?)
- sephware 8y agoThat's a good way to put it, and yeah I would agree that's how I like to use errors: give me the details I ask for and let me ignore the ones I don't care about. Sometimes an "error" isn't really an error, and at those times exceptions are overkill. Sometimes an error really is an error and I need to let the user know something went wrong, give them enough details to let them fix it and wait for them to try again.
- Skunkleton 8y agoBut wouldn't that look like: var s Settings if s, err := load_settings(); err != nil { s = defaults() } Where is the unhandled error?
- TheDong 8y agoNote that your code will not work; you've shadowed 's' inside the if block because you have 'if s, err := ...'. As a result, 's = defaults()' will set the shadowed 's' variable that only exists within the if block to defaults, but the 'var s Settings' you declared above will not be modified. Here's a playground showing the issue: https://play.golang.org/p/eE0HEZx1MJu https://play.golang.org/p/eE0HEZx1MJu Go is full of nice little foot-guns like that :) You would want to also have 'var err error' above the block and use '=' instead of ':=' to fix this sort of issue.
- Skunkleton 8y agoI am by no means an expert (or even a frequent user) of go. However, the most unfortunate foot cannon I have encountered is this: package main type HowOdd interface { Poke() string } type AConcreteThing struct { } func (t *AConcreteThing) Poke() string { return "hehe" } func DoAConcreteThing() *AConcreteThing { return nil } func DoAThing() HowOdd { return DoAConcreteThing() } func main() { lolWhat := DoAThing() if lolWhat != nil { panic("How could this happen?") } } I understand that the interface at the bottom is a non-null interface containing a null value, but...damn, that sucks.
- deleted 8y ago[deleted]
- merb 8y agoWell look at: https://golang.org/pkg/database/sql/#DB.Query https://golang.org/pkg/database/sql/#DB.Query How likely is the error going to happen, if you know (through tests and everything) that the query is correct? it can only happen in two scenarios: 1. the database has serious problems 2. the driver is incorrect in normal cases you would probably handle that with a middleware in classical languages. i.e. you would have a middlewre that catches exceptions and handle the error there (logging, paging, whatever) and maybe show a nice looking "we are experience problems now"-page. in golang this is a little bit harder, since you would need to handle the error by every caller and with the default http interface you would actually need to call your "handle default error" in every http handler.
- danmaz74 8y agoAn example is logging something to a remote server for analytics purposes: you can fire and forget.
- aikah 8y ago> these are purposeful trade-offs that the Go team makes. Trade-offs for whom or with what in mind? the compiler or the programmer? That's the "philosophical" difference between the Rust team and the Go team.
- Skunkleton 8y agoExactly. That is why Rust does so many more things, but Go compiles so fast. Even with two wildly different approaches to language design, each has their place, and their own set of drawbacks.
- repolfx 8y agoIt's a false dichotomy. Languages like Java or Kotlin compile fast and have exceptions too.
- hactually 8y agoNot quite - Java is faster than Kotlin [0] but I've never seen a Golang app take more than 10 seconds (and that's something huge like Kubernetes or Docker components) [0] https://medium.com/keepsafe-engineering/kotlin-vs-java-compilation-speed-e6c174b39b5d https://medium.com/keepsafe-engineering/kotlin-vs-java-compi...
- rhencke 8y agoThe article you link comes to a different conclusion: > With the Gradle daemon running and incremental compilation turned on, Kotlin compiles as fast or slightly faster than Java.
- mmirate 8y agoBecause the JVM takes another tradeoff against Go and Rust: it has a runtime interpreter+JIT, which causes even more performance overhead than Go's GC let alone Rust which - at runtime - is effectively a zero-cost abstraction over C and jemalloc.
- eptcyka 8y agoIf it would bring significant amount of technical debt to introduce some synctactic sugar that'd allow to bubble errors up the call stack without 3 extra lines of code, then design choices made for Go seem to be questionable. At least superficially.
- olooney 8y agoI agree with you, but it's important to acknowledge the strength of the argument against exceptions. I think Raymond Chen put forth some of the best arguments, claiming they were human error prone: https://blogs.msdn.microsoft.com/oldnewthing/20050114-00/?p=36693 https://blogs.msdn.microsoft.com/oldnewthing/20050114-00/?p=... https://blogs.msdn.microsoft.com/oldnewthing/20040422-00/?p=39683/ https://blogs.msdn.microsoft.com/oldnewthing/20040422-00/?p=... While forceful, I don't accept the conclusion of Raymond's argument. I feel it may be true for programmers primarily trained and experienced in C, but is not true in general. As such, the argument reduces to "programmers who are not familiar with exceptions sometimes make mistakes when using them." One could say the same thing about pointers, dynamic typing, lambdas, macros, comprehensions, pass-by-reference, etc. Today, most programmers are familiar and comfortable with exceptions, having almost certainly been taught to use them in college and almost certainly using them on a daily basis for their entire professional career. They'll also have been taught to use a language-specific toolbox such as RAII or try/catch/finally to deal with any potential problems. Once you get in the habit, it's not hard to scan through a program line-by-line asking yourself "what would happen if an exception were thrown at this point?" and to take appropriate precautions. In fact, I'd wager that for anyone who's spent years working in any language with exceptions this quickly becomes second nature. It's also an easy way to add value during peer code review. In my experience, writing correct code with exceptions is not "really hard," as Raymond argues, but rather no harder and a lot quicker that using explicit error handling. The reason it's a lot quicker is because "exit the function with an error status and do local cleanup of variables initialized so far" is by far the most common correct action. And for cases when its not, the try/catch/finally or other exception handling whatever is straight forward to write and no uglier than explicit error handling would have been. Of course, it's possible I think this because I've worked in languages with exceptions for most of my career. But I certainly don't observe that even the most junior programmers on my team create a ton of bugs that could be attributed to mishandled exceptions. In fact, I can only remember a handful of such bugs, mostly involving open database transactions or unhelpful error messages masking more detailed error messages. A more solid objection to language support for exceptions can be made by pointing out all invisible code generated by the compiler to correctly handle exceptions. This can lead to significant code bloat and in some cases can negatively impact performance. Or by pointing out how unwise it is to be allocating additional Exception objects while dealing with out of memory errors. These are some of the reasons why C++ isn't appropriate for an OS kernel, for example.
- networkimprov 8y agoGo 2 is likely to get a per-call variation of try/catch via named handle blocks, see: https://github.com/golang/go/wiki/Go2ErrorHandlingFeedback https://github.com/golang/go/wiki/Go2ErrorHandlingFeedback and this broad survey of error handling requirements: https://gist.github.com/networkimprov/961c9caa2631ad3b95413f7d44a2c98a https://gist.github.com/networkimprov/961c9caa2631ad3b95413f... Also the author overlooks the Error Values draft design, which is tentatively targeted for Go 1.13: https://go.googlesource.com/proposal/+/master/design/go2draft-error-values-overview.md https://go.googlesource.com/proposal/+/master/design/go2draf...
- TheCoelacanth 8y agoI believe handle blocks is exactly what they were referring to as "basically a reverse try-catch at best and a Visual Basic “on error goto” at worst".
- networkimprov 8y agoBased on the feedback page linked above, I believe what is likely for Go 2 is quite different than "check/handle". See the requirements page linked above for more.