Earlier quoted context omitted.
> Go's error handling is essentially the same as Error/Either/StatusOr (returning errors as values). Not really, it's very annoying to chain calls which can error. Also, as another commenter mentioned, functions which can potentially fail should return sum types and not product types. Compare: do first and first, err := computeFirst() if err != nil { return nil, err } second, err := computeSecond() if err != nil { re…
Apologies, I know very little Haskell - does that example mean that `computeSecond` will always be called, even if `computeFirst` failed? If it does, it's not the same as the Go code which will not call `computeSecond` in that case (which might be a requirement - who knows?) I'm also assuming that `f first second` will return (an error monad?) if either of `first` or `second` are (an error monad?) - is that right?
Go 1.13: xerrors
131–140 of 150 posts
Re: Go 1.13: xerrors
#132It seems like golang designers are totally isolated from what's been happening in the last 30 years in languages design. They still insist on their weird way of error handling just like they were stubborn for years and years on the lack of package management and eventually a very weird and rudimentary way of it. It's sad because I use this language extensively but its weirdly mediocre design is totally unfathomable.…
I've been using Go heavily over the last five years, starting with 1.2. Whatever warts the language has in its design, the error handling being one, it's still an excellent language for getting work done quickly, and correctly. I'm far more productive in it than Java, C++, or Python, and I'm old enough to have done lots of Pascal, Lisp, and more scripting dialects than I can count. Having been writing software over t…
Lisp is simple. Go is half-simple, but in its take on simplicity, it also takes away some constructs that make useful, high-leverage expressiveness impossible.
Some of its other benefits are appealing to me, but that's not one of them. It seems simple on its face only.
Re: Go 1.13: xerrors
#133Earlier quoted context omitted.
Rust's type system + the failure crate ( https://crates.io/crates/failure ) is the nicest I've seen. It's similar to Haskell in that errors are part of the return value of a function, and the type system enforces handling of this. _But_ Rust also includes some really nice syntax for passing errors through so I can write this: use failure::Error; fn foo() -> Result { may_return_an_error()?; might_return_a_different_er…
This sounds exactly like Java's checked exceptions.
Re: Go 1.13: xerrors
#134Earlier quoted context omitted.
> Once Java gets fibers, its concurrency offerings will be a strict superset of golang's. golang doesn't even offer event based async concurrency. Kotlin does that today and I like Kotlin, however the fact is that the class-everywhere Java approach just doesn't sync with me. Go's and Rust approach to OO with value-based types (structs) suits me much better. > golang doesn't even have concurrent data structures Not st…
> Kotlin does that today and I like Kotlin, Kotlin's coroutines are still not like fibers (it's still affected by: https://journal.stuffwithstuff.com/2015/02/01/what-color-is-... ) Java is getting record types as well. That being said, one is free to use whatever JVM language they like and still get the huge benefits of the JVM, regardless of the language. > Not strictly true. It does have sync.Map There's also 3rd p…
Agreed, but Java's generics are not the best either. When I am looking for an advanced type system in this space I look at Rust, not Java.
Re: Go 1.13: xerrors
#135It seems like golang designers are totally isolated from what's been happening in the last 30 years in languages design. They still insist on their weird way of error handling just like they were stubborn for years and years on the lack of package management and eventually a very weird and rudimentary way of it. It's sad because I use this language extensively but its weirdly mediocre design is totally unfathomable.…
And I am so happy that they won't do anything but the right thing. Over the decades as a programmer I have seen a lot of language come and go. A lot of languages suffer from "features". Where either a language is designed with advanced concepts getting either directly in the way of writing simple programs, or even worse, getting bolted on later on, creating something very different from the initial language. I love t…
If you like Go, you'll love the simplicity of Brainf-ck, a clean design which is easy to learn, simple syntax, and supported in almost all computing platforms.
Re: Go 1.13: xerrors
#136Earlier quoted context omitted.
> Go's error handling is essentially the same as Error/Either/StatusOr (returning errors as values). Not really, it's very annoying to chain calls which can error. Also, as another commenter mentioned, functions which can potentially fail should return sum types and not product types. Compare: do first and first, err := computeFirst() if err != nil { return nil, err } second, err := computeSecond() if err != nil { re…
Apologies, I know very little Haskell - does that example mean that `computeSecond` will always be called, even if `computeFirst` failed? If it does, it's not the same as the Go code which will not call `computeSecond` in that case (which might be a requirement - who knows?) I'm also assuming that `f first second` will return (an error monad?) if either of `first` or `second` are (an error monad?) - is that right?
return is a bit of a misnomer in Haskell -- it really means "wrap this value in the monad supplied by the context." So as other commenters have mentioned, f(...) cannot fail. Non-monadic Haskell functions never use return.
If f could fail and you indeed wanted to propagate its error if it did fail, you could write the code as
do first Re: Go 1.13: xerrors
#137Earlier quoted context omitted.
And I am so happy that they won't do anything but the right thing. Over the decades as a programmer I have seen a lot of language come and go. A lot of languages suffer from "features". Where either a language is designed with advanced concepts getting either directly in the way of writing simple programs, or even worse, getting bolted on later on, creating something very different from the initial language. I love t…
>I love the dependable simplicity of Go. If you like Go, you'll love the simplicity of Brainf-ck, a clean design which is easy to learn, simple syntax, and supported in almost all computing platforms.
Re: Go 1.13: xerrors
#138Earlier quoted context omitted.
> Java, C++ and Python have exceptions to keep you from littering your code with error handling, and code with exceptions is hard to read. The line of code you are looking at any point in time may instantly jump to another place, effectively, Rust and Swift both manage to make error handling easy while keeping this nice "errors are just values" property. Go could easily have added Rust-like or Swift-like error handli…
How is rust error handling better than gos?
It's better in many ways.
Firstly, rust has sum types, so it's possible to have exhaustive matches and know you've handled every case. This isn't possible in go. For comparison:
// go
val, err := doSomething()
switch err.(type) {
case *SomeErrorType:
// handle
default:
panic("inexhaustive error check (at runtime, only if that error type is hit)")
}
// rust
let (val, err) = do_something()
match err {
Err::SomeErrType(inner) => { /* handle */ },
}
// won't compile if the match isn't exhaustive
Note as well that you have to return the error interface, not some more specific type, in go because of the "nil struct is not a nil interface" gotcha. Juggling around structs that are returned as errors is basically impossible to do safely, so everyone returns the error interface. This is another way the language causes error handling to be worse.Next, generics in rust allow for nicer chaining of computation in the presence of errors. Let me show you two examples. Again, the go and rust code is as identical as I can make it:
// go
val1, err := computation1()
if err != nil {
return nil, err
}
val2, err := computation2(val1)
if err != nil {
return nil, err
}
return computation3(val2)
// equivalent rust
computation1().and_then(computation2).and_then(computation3)
// also equivalent rust
let val1 = computation1()?;
let val2 = computation2(val1)?;
computation3(val2)
The ability to have a generic 'Result' type to chain computation allows for code to be more readable, while still having all the benefits of errors being values.The ability to have a generic 'Option' instead of 'nil' also is very helpful, but enough has already been written about null pointers that I don't wish to rehash it here.
Finally, in practice, rust's higher level features (namely macros) allows libraries to create very powerful developer abstractions around errors, like those offered in the 'failures' crate, all without having any runtime overhead.
In practice, all of these things also combine to result in libraries offering better error types and allowing callers to handle errors well.
Re: Go 1.13: xerrors
#139Looking forward to shit storm once they introduce generics in near future. I am sure people will still complain that this is not how parametric polymorphism should be implemented.
Re: Go 1.13: xerrors
#140Earlier quoted context omitted.
I've been using Go heavily over the last five years, starting with 1.2. Whatever warts the language has in its design, the error handling being one, it's still an excellent language for getting work done quickly, and correctly. I'm far more productive in it than Java, C++, or Python, and I'm old enough to have done lots of Pascal, Lisp, and more scripting dialects than I can count. Having been writing software over t…
I keep checking in on Go, trying to decide if I want to add it to my toolkit, but this argument usually bugs me. Lisp is simple. Go is half-simple, but in its take on simplicity, it also takes away some constructs that make useful, high-leverage expressiveness impossible. Some of its other benefits are appealing to me, but that's not one of them. It seems simple on its face only.