story
How about you study the language a bit more in depth (including estabilished idioms) before pontificating about it?
I'll note that The Fine Article is about why one of those established idioms confuses newcomers. Even better, it bites people because the type of an interface needs to be nil for something to work. (Insert appropriate expression of astonishment here.)
Enforcing patterns hiding inadequacies in the implementation works less well than one would imagine, e.g. look at all the languages that Go sought to improve upon and the baggage of "design patterns", GoF-alikes, etc. that they brought with them.
> return early
I was just going off what I found at https://blog.golang.org/error-handling-and-go.
I assume you meant this (in Go-ish pseudocode)?
result, err := Foo1()
if not err {
Panic(err)
}
result2, err2: = Foo2(result1)
if not err2 {
Panic(err2)
}
This might allow you to skip the nesting of blocks, but why would you do this when multiple languages exist where you don't have to thread around error messages everywhere? For instance, result1 <- foo1
result2 <- foo2 result1
(Yes, that's Haskell syntax, but you can do things with a similar lack of pain/verbosity/error-prone-ness in many languages.)At the end of the day it doesn't make any more sense to apply Haskell methodologies to Go than it does to complain that Haskell is missing some fundamental features of Go. They're distinctly different languages. But despite this I've noticed you spend a lot of time in various Go discussions on HN moaning that Go isn't more like Haskell.
https://rustbyexample.com/std/result.html
Ergonomic error handling or generics/parametric polymorphism aren't "Haskell methodologies". Go is one of a very small number of languages that have been designed in the last decade and lack features like this.
The reason I participate in HN comment threads about Go is largely how entertaining I find comments strenuously rationalizing Go's inadequacies. In one (very recent but definitely memorable) case[1], I was told that
> You [should] first reconsider your need to make a generic data structure and evaluate on a case by case basis.
2. I think the arrow means assignment in Haskell and you are just referring to monadic errors? To use them the same way proper error handling is done in Go, you would just have more nesting and multiple unwraps, which is marginally different than Go syntax (but definitely with more compiler checking.) The arrow syntax in Go is used by channels.
a, err := squareRoot(x)
if err { handle(err) }
b, err := log(a)
if err { handle(err) }
c, err := log(b)
if err { handle(err) }
you can just use an optional ("Maybe") type: write a, b, and c with types like a :: Double -> Maybe Double
and then do a <- squareRoot x
b <- log a
c <- log b
If the computation of a fails, the whole computation fails. The compiler takes care of all the error-checking plumbing. I think the ergonomics of this common kind of situation are really suboptimal in Go, which to my knowledge doesn't support anything remotely similar.