14 ms·
I think two big failures were: 1. Nil pointers (two types of them, even!). We knew better even then. 2. Insisting that the language doesn't have exceptions, w
by knorker 3y ago
I think two big failures were:
1. Nil pointers (two types of them, even!). We knew better even then.
2. Insisting that the language doesn't have exceptions, when it does. User code must be exception safe, yet basically never use exceptions. The standard library swallows exceptions (fmt and http)
Those are the biggest day to day concrete problems. There are many more that are more abstract, but also hurt.
- randomdata 3y ago> Insisting that the language doesn't have exceptions Insist in what way? The Go website insists that Go has actual exceptions, unlike the pretend exceptions that are actually errors passed around using goto like you find in Java and other languages inspired by it.
- lokar 3y agoSo many people confuse errors with exceptions
- groestl 3y agoErrors are just checked exceptions where you get the chance to introduce bugs, by unrolling the stack manually.
- randomdata 3y agoErrors are things that can fail after the program is written (hard drive crash, network failure, etc.). Exceptions are things that were already broken when you wrote the code (null pointer access, index out of bounds, etc.) To put it another way, exceptions are failures that a sufficiently smart compiler would have been able to catch at compile time. Of course, creating a compiler that smart is a monumental task, so we accept catching some programmer mistakes at runtime as a reasonable tradeoff.
- groestl 3y ago> exceptions are failures that a sufficiently smart compiler would have been able to catch at compile time Would love to see your proof of this for stack overflow exceptions. You could become very famous.
- randomdata 3y agoIf you are trying to suggest that the stack is runtime unpredictable like a hard drive, overflowing it would be an error, not an exception. Therefore, a sufficiently smart compiler just needs to ensure that you have done the proper accounting of stack use and handle the error condition if you are approaching an overflow state. With that, you can prevent it becoming an exception. If you encounter a stack overflow exception, it is because you didn't do your due diligence. Technically your program is flawed. Granted, the pragmatic engineer probably doesn't care about correctness in that area. It turns out not all programs have to be perfect to be useful. No fame for me, I'm afraid. There is nothing here out of the ordinary.
- monocasa 3y agoGiven how they being up how fmt and http swallow them, I believe the parent is referring to panics rather the errors returned via standard control flow.
- randomdata 3y agoYes, that's what we're talking about (exceptions, or panics if that's what you want to call them). That's what exceptions are.
- monocasa 3y agoI guess I'm confused since panics are equally errors passed around by gotos as much as java exceptions are. Probably more so since at least with java it ends up being part of the the function type signature the vast majority of the time.
- everforward 3y agoIt creates 2 disparate types of error handling that don't neatly mesh together. You have to handle error return values, but you also have to handle exceptions (panics) because they still exist. My issue is mostly implementing both ways of bubbling up an error to somewhere it can be handled. I think having either error return values or exceptions is preferable to having both. I don't think exceptions are perfect, but if panic() absolutely has to exist then I'd rather have an entirely exception-based language than a language that uses both systems simultaneously. E.g. if I write a function that accesses an element of an array without bounds-checking, it could panic and I have to handle that exception. Bounds-checking basically just becomes finding things that would throw exceptions and converting them to errors so we can pretend that exceptions don't exist.
- randomdata 3y ago> It creates 2 disparate types of error handling They are disparate conditions. Errors happen in response to conditions that occur during the execution of the application. Exceptions happen in response to conditions that occurred when the code was written. Very different things. It is highly unlikely that you want to handle an exception. It's the runtime equivalent of a compiler error. Do you also want to handle compiler errors so that your faulty code still compiles? Of course not, so why would you want to do the same when your coding mistakes are noticed at runtime? There are, uh, exceptions to that when it is necessary to handle exceptions, but if it you see it as routine you're doing something wrong. If you overloaded that with errors, forcing it to be routine, you'd have a nightmare on your hands (like in those other languages that have tried it).
- stonemetal12 3y agoOther than the fact that they spelled "throw" "panic", "catch" "recover", and "finally" "defer" how are go exceptions different than what you find in java? I get that Go devs like to claim they are completely different because you are supposed to use them differently, but under the hood they are identical as far as I can tell.
- eweise 3y agoNot sure why people downvote instead of answering the question.
- randomdata 3y agoThe comment answers its own question. As to why press a button that does nothing? For the same reason fidget spinners were all the rage a few years back: Bored people like to do something with their hands. Perhaps if the comment had a question that was left unanswered, people wouldn't have become so bored?
- eweise 3y ago"how are go exceptions different than what you find in java?" They are not the same. Thought someone might be helpful and list the differences.
- randomdata 3y agoWhy not lead by example?
- eweise 3y agoAlready been done by other posters in the thread so you can stop your snarky comments.
- randomdata 3y ago
- knorker 3y agoNot sure what your question is. "Insist in what way": starts with things like the Go FAQ having a question called "Why does Go not have exceptions?". The answer does elaborate, so it's not like they're lying, exactly. But anything and everything Go says about this also applies to C++. There's no relevant technical difference between Go and C++ exceptions, nor is there a difference in how the standard library uses them. ... except the Go standard library swallows exceptions in some cases, which is like the biggest no-no you can do. But nobody would say that C++ doesn't have exceptions.
- randomdata 3y agoGo clearly has exceptions. It always has. Thus I ask what is being insisted. Like, specifically. Is it being insisted in some tangential way, like 'Go doesn't have "try", "catch", and "finally" keywords'? Something like that would be true. Or is the insistence straight up "Go does not have exceptions!"? If that is the case, who is saying it? Did you just read it in one of the regularly scheduled Rust advertisements that get posted here? Or did it come from someone who actually means something in the Go community?
- knorker 3y agoLike specifically what I just mentioned: the official FAQ. And repeatedly from Pike, core documentation, and other core developers.
- randomdata 3y agoHuh? There is nothing in the FAQ claiming that Go doesn't have exceptions... It literally says that Go does have exceptions. Are you referring to the frequently asked question itself? That's the only thing in there that could even possibly make you think Go doesn't have exceptions. Except, being a FAQ, you know that the question comes externally from people who don't know about Go. That is why they are asking the Go people the question! One would have to be braindead to think that is an insistence. Maybe you need to be even more specific.
- tptacek 3y agoGo has been my daily driver for over a decade. I was in the past a C++ programmer. In what ways am I writing exception-safe code when I write ordinary Go code?
- monocasa 3y agoI've run into issues where panics cause half of what should be a multistep but assumed to be atomic transaction to occur, putting the system into a goofy state that required fairly manual intervention. In my case a system daemon that required someone to manually fix up system state on the CLI and restart the system.
- tptacek 3y agoThat's like, strong-form exception safety, a problem in most mainstream languages. But when C++ people talk about "exception safety", they're talking about basic or weak-form exception safety: not leaving dangling pointers and resources as a result of unexpected control transfer. That style of defensiveness is not common in Go code.
- monocasa 3y agoWell that's the thing, I am talking about resources left 'open' since they didn't complete their lifecycle due to the unexpected control flow. Yes, it's not common in go code, but I think that's more a combo of the GC making dangling memory not a problem, and the environment that most go code lives in (ie. kubernetes clusters or some equivalent) where the other resources leaked are eventually reclaimed by the autoscaler and other devops automation. The GC is ubiquitous, and definitely a point in favor for go for the vast majority of use cases, but I've found it more difficult than anticipated to write go code that manipulates resources other than memory that the environment you're running in won't clean up for you. And that's coming from C++ code originally including the exception safety issues.
- Smaug123 3y ago(By the way, [the Austral spec](https://austral-lang.org/spec/spec.html#rationale-errors https://austral-lang.org/spec/spec.html#rationale-errors) discusses in great detail the available tradeoffs in this area of language design.)
- __turbobrew__ 3y agoPanicing on nil pointers is definitely the thing which I have seen cause the most pain.
- silvestrov 3y agoThe ?. (optional chaining) operator in Javascript is really a godsend for this. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Optional_chaining https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe...
- tialaramex 3y agoRight, people really need to take Tony's Billion Dollar Mistake more seriously, which means no you can't have "null" or "nil" or whatever you're calling it. We know that's a bad mistake so you shouldn't repeat it. Just as I can excuse using a fat pointer to some bytes as your "string" type in a very close to the metal language. I can excuse the possibility of a null pointer or reference in such a language, just above the level where we're doing machine code. It's not nice, but you're banging rocks together and there's a zero value in this register and so fine, let's have a "null" pointer. This is not something to be proud of, it shouldn't make its way into code that can avoid it, but it will need to exist in the very heart of the fire. Go is far above that level, so it needs to just not expose Go programmers to Tony's mistake at all. It should have been defined out of existence.
- 015a 3y agoI tend to feel, just error handling in general. Its not even something I'd care so much about, if it didn't seem like everyone else felt like the way Go does errors is great. You can't/shouldn't do custom error types, even though its an enticing sexy interface, because of things related to the massive nil/nil mistake you've covered. We had errors-as-values in popular, large languages (Javascript callbacks?), and by the mid-10s everyone recognized that they're kinda whatever, mostly just a different way of doing the same thing less conveniently, and that community got rid of them (as a side-effect of the more general push to get rid of callback hell, but certainly no effort was made to keep errors-as-values around). We say "being forced to handle errors is great in Go", but (1) you don't have to handle them, you just have to acknowledge them with `_`, and (2) Java has had checked exceptions for years, and everyone also recognizes that those are ish. And, as you say, Go has two fundamentally different kinds of errors functions can throw (what color is your function?), except the facilities for handling panics are essentially a goto (which, I love pointing out lest we all forget, go also has literal goto). Sure, working code shouldn't panic; but all that asserts is that Go wasn't designed to be fault tolerant. To be clear, I don't feel as much passion for hating on Ruby, because I don't use Ruby. I use Go. I don't wish to hate on the language for the purpose of hate; I wish that more people would agree that the situation is quite poor, rather than good, and that we could make meaningful positive change to the language.