

Honestly, I kinda like if err != nil {. It forces me to think more carefully about how I want errors handled than something like throw does.
I don’t feel like I have experience with that many different languages. Maybe there’s another language that does it in a way I’d like better. But I prefer Go’s model over the way, say, Java, JavaScript, or Python does things.






















Well, I don’t like it. Lol.
Adding something like monads to Go as some first-order kind of thing really feels to me like it would be a big bag on the side. (I mean, I feel like all the functional stuff in Java like lambdas and streams and stuff is a bag on the side in the same way. Java fanboys back in the day touted Java’s proceduralness as a strength. Now I have to wonder whether those fanboys have left Java for other languages and the Java fanboys we have now are a new crop of lambda-positive Java fanboys or whether the old Java fanboys changed their tunes and decided functional programming was a good thing for Java after all.) It’d make Go kindof not Go any more, making it “just another language that adds features willy-nilly”.
Plus, changing the standard library to use monads instead of multiple return values for errors would be a huge backwards-incompatible thing. Not to say backwards-incompatible changes shouldn’t be made. (I have great respect for Python’s 3.0 rework, for instance. And I think Java is extremely overdue for something similar.) But I don’t see adding monads as a benefit at all, let alone worth the effort of migrating.
I’m sure part of the reason why most of the previous proposals haven’t been accepted is because it would create tons of interactions with existing Go functionality and/or confusing edge cases, each of which would have to be considered.
I just googled (DuckDuckGo’d, actually) and ran across this proposal. I’m not sure I hate… something roughly like it (yet). But it’s not as if it doesn’t have any costs.
My thoughts on it:
count := strconv.Atoi(input) ? err { return err }(rather thancount := strconv.Atoi(input) ? { return err }.) (I’d probably be ok with omitting that variable name after the?rather than requiring an underscore if that value wasn’t used in the body of the block… if I convince myself I’m ok with even the basic premise, that is.)errortype”, so I’d rather the?construct assign the positionally-last return value to the more locally-scoped variable (whose name is after the?) than requiring that variable to be of any particular type.countbe visible within that block”? Usually a variable is not defined until after the statement that declares it, but this new block would be… part of the statement that declares it, which makes it kindof weird for that variable to be visible inside the block. I concede it would be useful to be visible inside the block, but it still makes scoping confusing, which isn’t an insignificant cost.?expanded to other situations. Likefunc bob() (int, error) { ... } ; func(i int) { ... }(bob()?)to silently suppress the error thatbobreturns. But one major cost of that would be that there’s no rule that “if you return an error, the other return values must be the zero value of the associated type”. It’s a common convention, but not so common as to be inviolable. If, say, a library did return something specific rather than the zero value when returning an error, it would probably have to devote a lot of extra documentation to that situation because that’s a pretty confusing corner case. (Like, maybe a function returns a coefficient to be multiplied by something, but does areturn 1, fmt.Errorf("...")if something fails because you’re more likely to want a1in an error condition where you’re multiplying that value by something than a0. (Or maybe that case would be better with a 0.))if err := bob(); err != nil { ... }convention:count := strconv.Atoi(input) ? err { return err }Honestly, the more I think about it just while writing out my thoughts above, the more I think it isn’t worth it. There is one poposal for error handling that I can say I “like” without reservations, though. (And it seems the core Go team is, roughly, planning to take that route.)
If I had to pick a biggest frustration with how Go is, it would probably be
nil. I kindof wish it didn’t have that or anything like it. Not to say I’ve thought it through. There may be really good reasons whynilhas to exist. But maybe it would be fine for the zero value of a function to be a function that does nothing but panic. And the zero value of a map to be an empty map. And the zero value of a pointer to be a pointer to a zero value of the pointed-to type. Etc. I don’t think it’s worth changing that at this point, though. I’d rather just use Go as it is than have Go embark on such a drastic change.