Hacker News new | past | comments | ask | show | jobs | submit login

> What does it have to do with errors?

The fact that the former scenario is much more likelier to happen in golang due to its error handling. The former can be caught using unit tests, and should stick out more in languages like Java with scoped try-with-resources blocks that limit the scope of lifetimed variables (another bad design in golang where defers are function scope, not local scope limited, introducing unnecessary runtime costs, while also being less useful in practice).

At the same time, you don't want to be writing unit tests for every simple scenario. Some people who use dynamic languages argue that you just type assert everything in unit tests and you should be good. Obviously, that's not how things work out in practice. Similarly here, because of the way errors are handled in golang, the same pattern is everywhere in the program, and it is extremely tedious to write the same unit tests over and over everywhere, while making sure to reach a certain level of coverage.

> Not all Go functions, even in the standard library, return errors declared using the error interface.

Do they just return integers then like C?

> Why would you ever need a stack trace when the network is down, for example?

Because it's still important to know where you are in the program when the network broke, in order to make sure that recovery happened correctly for example. Seeing a "network is down" error in the logs is useful, but more so is knowing exactly what I was doing (what if I wasn't expecting to access the network in a particular path? etc.)

> Every problem you encounter with errors will also be encountered with other types sooner or later.

Practicality matters, otherwise C is all we'd ever need, and we wouldn't be having constant CVE's etc.

> Mentioning Rust here is a is a bit strange seeing as how it contradicts the entire premise you're trying to push.

Not really. Rust errors compose nicely, and you're explicitly forced to handle them (unlike golang's), and are much harder to accidentally swallow or ignore compared to golang. This scenario is repeated many times when you compare golang to other better designed languages. The language constantly takes the easy way out so to speak, making the compiler implementation simpler, while pushing complexity onto the user. Furthermore, as I pointed out, there's nothing preventing us from using the same approach in Java, now that it has sealed types and pattern matching.

That is not possible in golang due to its lack of support of all those constructs. Now with generics, some people are starting to use some similar approaches, but they fall flat on their face because (1) golang doesn't have those constructs as I mentioned, but also (2) the way generics have been implemented in golang (similar to the rest of the language) are simplistic (you can't have types on member functions), leading to further abominations and verbose code.

Java's checked exceptions are not much different actually. They still require you to handle the error either by try/catch or by declaring that the method throws the same exception, or a superclass of it.

I also remembered another shortcoming of golang error handling that I've seen several times in real code bases, being forced to check both the error and the other return value to make sure that things are working. Yes, a properly written program shouldn't need to do that, but reality doesn't care. And what's ironic is that golang was supposed to be designed to support "programming in the large" (another unverified claim that is contradicted by reality). The fact that it opens these doors is indicative of the mentality that went into designing it.




> At the same time, you don't want to be writing unit tests for every simple scenario.

Yup, exactly. In a perfect world you would, but the world ain't perfect. Sooner or later you're accidentally deleting the wrong thing because you didn't test it/didn't test it correctly.

And for what reason? A language can guard against that kind of mistake quite well.

So, that still leaves us wondering why you don't find it advantageous for a programming language to be able to deal with these kinds of problems unless the problem is related to an error? If you have a solid foundation the problem with errors you are trying to show would disappear. Go only has problems with errors because it also has problems generally.

> Practicality matters, otherwise C is all we'd ever need, and we wouldn't be having constant CVE's etc.

Agreed. Which leaves it to be insane to only want to fix the problems with errors when everything wrong with errors is also wrong with every type. If you fix the error problem properly you've automatically fixed it for all types. Why on earth are you suggesting that you'd purposefully make the fix harder just to ensure that it only fixes errors?

> Rust errors compose nicely, and you're explicitly forced to handle them (unlike golang's), and are much harder to accidentally swallow or ignore compared to golang.

This isn't a feature of specialized error handling, but Rust's overall design towards helping with general state management. Rust alleviates the same problems for all types. Rust yet again shows us that errors aren't special and don't matter. Provide a good foundation for state management and managing error state becomes easy by virtue of just being yet another state. You are able to cleanly deal with errors in Rust because it took care to get the problem right generally, not because it took care to worry about errors at the expense of everything else.

Go could, like Rust, do more to help with general state management. It would be insanity to try and only do that for errors, though.


How do you suggest golang handles stack traces then?

It seems Rust has the same issue by the way: https://docs.rs/error-chain/latest/error_chain/

> If the RUST_BACKTRACE environment variable is set to anything but 0, the earliest non-foreign error to be generated creates a single backtrace

If my understanding is correct, it means that you won't get stack traces for any external libraries or code that does not use this library.

Because Exceptions in Java/C#/etc. are special, you will always have stack traces regardless of which code you're calling.




Join us for AI Startup School this June 16-17 in San Francisco!

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: