- it isn't a priority
- it is a tricky thing to get right in the context of Go
- there haven't been any satisfactory proposals thus far
If this isn't quite right I'd love to be corrected.
In the meantime there have been several satisfactory proposals (in the lists and elsewhere), and it's not like 200 other languages implementing Generics have had many issues with them.
So, it boils down to the Go core team putting up the solution to an impossible tradeoff as the holdback (and a little exagerrated one at that, with relation to the costs involved).
And then, they said "the language won't change" etc recently.
It’s not without warts. You can bail with panic(), which is essentially a throw.
It’s tedious to handle errors, but that’s because actually handling errors is tedious.
I'm not joking when I say it really is that easy. Go makes it (and, really, many other things) very difficult for reasons that are at best murky.
This is effectively like doing this in Java:
try {
DoX()
DoY()
DoZ()
} catch( Exception ) {
// The code has no idea what failed here.
}
Whereas, the go code looks like this: if err := DoX(); err != nil {
// handle error from DoX
}
if err := DoY(); err != nil {
// handle error from Doy
}
if err := DoZ(); err != nil {
// handle error from DoZ
}
This is what Go programmers means when they say "actually handle the errors". At each step you handle the specific failure from the specific call. It's somewhat more verbose, but it's a LOT more robust against real life failures.If you only care about whether something succeeded use Option, if you care about the error use Either, Validation, etc.
Just pick the right Monad.
The first exception hit pops out the other side and you pattern-match against it. So, the one that did file access and returned a FileNotFoundException. If you have multiple pieces of code that can return FileNotFoundExceptions, you can pass a message in the exception, just like any other Java exception. You can often be more type-specific, too. Bear in mind that defining a new exception in Scala is a one-liner, and you can encapsulate your FileNotFoundException in a RetrievalFailedException very easily and cleanly.
Your method is not more robust, I assure you--it's just verbose and both typo- and thinko-prone.
An that is what makes go awesome. In java or php, you, as a developer, can never know wether the functions you are calling will throw an exception. The only way to know? Read the doc, if you're lucky and there's a doc, or read the code... The result? your program will crash if you didn't add your try..catch block.
Go forces you to either explicitly ignore errors (and your fellow co-worker will know you did it on purpose) or deal with them. No surprises.
That's what checked exceptions are for in Java.
(I'm not sure if that was your understanding or not)
"The panic and recover functions behave similarly to exceptions and try/catch in some other languages in that a panic causes the program stack to begin unwinding and recover can stop it. Deferred functions are still executed as the stack unwinds. If recover is called inside such a deferred function, the stack stops unwinding and recover returns the value (as an interface{}) that was passed to panic."
That's true...but no different from "exceptions can only be caught in catch blocks".
> which makes them significantly different from exceptions that I'm used to that can be caught in any part of the code.
It doesn't make them any different from exceptions -- just as a catch block can be anywhere up the call chain, a deferred function can have been set anywhere up the chain.
Defer is basically "finally", except the position is different, and "recover" inside it lets it also do what "catch" does.
non-static typing is a massive loss of safety.
It's the "nice to have" things that make programming easier/more correct/better.
[1] https://hackage.haskell.org/package/base-4.7.0.0/docs/Data-L...
Yeah, the native fundamental collections are generic.