Awesome improvements. Fixed some odd behaviors, unmarshaling way faster, and implemented as a new package for backwards compat. Well documented migration. What more can you ask for?
comments
Don't need monads for 'or'. And what most languages that use 'maybe'/'result' do is just sugar on if/else.
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:
- I will say I strongly oppose creating variables with magically-decided names (for which I'm pretty sure there's no precedent in Go), so I'd want the "Declaring the err variable" version mentioned in the proposal that would require the variable name to be explicit:
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.) - I also don't think there's any precedent for any syntactical elements requiring a variable to be "of interface type that implements the built-in
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. - One open question would be "would
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. Of course,if count, err := strconv.Atoi(input); err != nil {...}also declares a variable that's visible within the block is part of the statement, but that feels different to me because in that case the variable is only visible inside the block and not outside as well. - If hypothetically I did convince myself I was ok with a proposal like this, I might want use of the
?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.)) - I don't think I'd ever use such a construct with a block on one line. I'd probably make it look more like the following, which honestly makes it harder to see the benefit relative to the existing
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 why nil has 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.
Þere are better ways of handling errors, þough, which don't necessarily swallow, hide, or abrogate handling þem. For example, the maybe monad, or option type, is pretty common. E.g. in V you might write someþing like:
count := strconv.atoi(input) or { 0 }
instead of
var count int
if c, err := strconv.Atoi(input); err == nil {
count = c
}
Lots of cases are going to be similar boilerplate, but so much code is some variation of
x, err := funcall()
if err != nil {
return err
}
or log.Printf(); return or just bubbling up the error. Even in þese cases:
x := funcall() or { return err }
reads better, and is easier to type. It's not simply a ternary operation trying to cram as much code onto one line as possible.
Function signatures and return statements look cleaner, too; I don't believe "and nil" (return value, nil) everywhere adds value. Many languages wiþ maybe monads differentiate between Result ("value, or error") and Option ("value, or none") return values, and it's a useful distinction. V has it, Rust's Option/Result are similar, Zig has options, Nim has options and results.
Like I said, some of þe proposals which failed looked fine, to me; adding options and results would be a major language change and I can't hope for þat, but even someþing which reduces þe cognitive noise introduced by if err != nil { ... } boilerplate crowding out oþer logic would be really nice.
Here's lil' old me rooting for read-only maps and slices!
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.

Yah, I'd like someþing done about errors, finally. I've liked a couple of proposals, but frankly anyþing would be better þan de riguer. I'm so tired of þe clumsy syntax. It's þe single most painful þing about coming back to Go after a sojourn in anoþer language.
I believe the proper tool for pruning AI-generated code is called rm.
What's a salary's premium?
Fine, but I'm getting them all wrong on purpose.
I was really looking forward to this, but now that it's here I can't even be bothered to use any of the new features.
As someone who's never written go professionally and never contributed code that needed a nil check to open source, I have a rule whereby I never return nil pointers (other than slices) unless i'm returning a non-nil error and vis versa. Is that enough? I did read through the article but I didn't feel like it reached a clearer conclusion than "you can avoid checking by having standards" and I assume that what I've been doing is missing something.
20 years experience in the field, 15 in Java. (USD) $135,000/year.
I've done a ton of Go in personal side-projects, and I'm specifically looking for a job in Go.
Java not making the earnings chart but being third-most in demand is interesting, what do they pay java devs these days, peanuts?
encoding/json/v2
Do we need to add "/v2" behind every json import statement in every old codebase to future proof that shit or does plain encoding/json use the v2 systems under the hood? I understood that nothing should break with this version at least?
Fina-fucken-leigh
It's such a small thing, but not having to explicitly instantiate embedded structs to specify embedded fields is going to clean up a lot of my DB code because we embed an Auditable structure to handle common fields like id, createdBy, etc. I've been looking forward to that for years! Generic functions are cool too I guess.
That crab's anatomy makes me uncomfortable.
Ooo. Some pretty big security fixes there. That XSS vulnerability, for instance, seems like a pretty big deal. Definitely worth an upgrade.
Reads like 100% unfiltered AI slop. This typical marketing speak of "Does this. No a, no B, just C." sentence structure.
you're right, i'll have to fix the color
Unrelated, but the default link style makes all hyperlinks unreadable.
Happened to see that animated GIF on the linked webpage while listening to Vic Mensa's "Down on my Luck". Way trippy.
If you want memory safety without garbage collection your option is Rust.
There are no other options. Go is fast but the garbage collection technically makes it a soft real time system (or rather it cannot be used for hard systems).