With generics Go is opening up the possibility of honest sum types. But, to be honest, I'm one of those people who are not upset by Go's error verbosity. The error shortcuts in Rust confuse me more often than not.
With generics Go is opening up the possibility of honest sum types. But, to be honest, I'm one of those people who are not upset by Go's error verbosity. The error shortcuts in Rust confuse me more often than not.
Not sure how it’s an issue, you just could not use the shortcut for this “not common” situation, or the case where the result is an actual product.
That Rust added ? Did not make every developer forget how to process values.
> The error shortcuts in Rust confuse me more often than not.
I have a hard time understanding that. The desugaring is hardly complicated, and the semantics are straightforward.
But the whole point of Go is that code is more often read than written, so legibility is paramount. Having a `?` operator alongside the traditional `if err != nil` would be very confusing.
Are you confused by unnamed returns? By the ability to declare variables initialised or not? By there being two syntaxes to declare variables? By it being possible to elide types in declarations or parameters lists?
Go is already full of shortcuts which I would say are more confusing and less useful than`?`
func foo() error { ... }
func bar() (string, error) { ... }
func baz() (string, int, error) { ... }
func doStuff() error {
foo()?
s1 := bar()?
s2, i2 := baz()?
}Anyways, you're entirely free to use a named return value in the second (or later) part of a multi valued := statement. An example is noted below, the clunky and obvious branches are there, but the intent and flow is obvious at a glance.
[1] https://go.googlesource.com/proposal/+/master/design/go2draf... [2] https://github.com/golang/go/issues/32437#issuecomment-51203...
Effective Go, on if: https://golang.org/doc/effective_go#if
It only promotes the concept that of using guard-clause style ifs that return an error and have no else clause, gradually eliminating each possible error condition. This style of programming was later termed in the Go community "Aligning the happy path to the left"[1][2]
[1] https://medium.com/@matryer/line-of-sight-in-code-186dd7cdea... [2] https://maelvls.dev/go-happy-line-of-sight/
I wholeheartedly agree that this style makes code more readable and I have adopted it - and encouraged others to adopt it - in other languages besides Go. This style would stil be followed with the try or check/handle proposals. For instance, let's take the example:
f, err := os.Open(name)
if err != nil {
return err
}
d, err := f.Stat()
if err != nil {
f.Close()
return err
}
codeUsing(f, d)
f.Close()
return nil
With the simple try proposal that would be: f := try(os.Open(name))
defer f.Close()
d := try(f.Stat())
codeUsing(f, d)
With OP's variant of the try proposal, using a question mark this is arguably even more readable (less noisy): f := os.Open(name)?
defer f.Close()
d := f.Stat()?
codeUsing(f, d)
As you can see, these proposal reduce - not increase - nesting, so they are completely in line with what Effective Go is saying.```x := potentiallyBuggyFunction ? genericErrorHandler("log message here", http.StatusNotFound,...)```
Where the `?` is kind of like a null coalescing operator, it might help?