This is at least the biggest release since 1.18 with generics, possibly bigger. I’m excited because the changes demonstrate a transition from the traditional go philosophy of almost fanatical minimalism, to a more utilitarian approach.<p>Loop variable capture is a foot-gun that in the last six years has cost me about 10-20 hours of my life. So happy to see that go. (Next on my list of foot-guns would be the default infinite network timeouts — in other words, your code works perfectly for 1-N months and then suddenly breaks in production. I always set timeouts now; there’s basically no downside)<p>Interesting to see them changing course on some fundamental decisions made very early on. The slices *Func() functions use cmp() int instead of less() bool, which is a huge win in my book. Less was the Elegant yet bizarre choice — it often needs to be called twice, and isn’t as composable as cmp.<p>The slog package is much closer to the ecosystem consensus for logging. It’s very close to Uber’s zap, which we’re using now. The original log package was so minimal as to be basically useless. I wonder why they’re adding this now.<p>I’ve already written most of what’s in the slices and maps packages, but it’ll be nice to have blessed versions of those that have gone through much more API design rigor. I’ll be able to delete several hundred lines across our codebase.<p>What’s next? An http server that doesn’t force you to write huge amounts of boilerplate? Syntactic sugar for if err != nil? A blessed version of testify/assert? Maybe not, but I’m happy about these new additions.
It is interesting to see them add things like the "clear" function for maps and slices after suggesting to simply loop and delete each key one at a time for so long. Is this a result of the generics work that makes implementation easier vs. the extra work of making a new "magic" function (like "make", etc.)?
Huh, I'm glad to see generic Min/Max functions, but the fact that they're built-ins is a little odd to me. I would have expected them to put a generic math library into the stdlib instead. The fact the stdlib math package only works with float64s has always struck me as a poorly thought out decision.
I'm a bit surprised that the slog package was added to the stdlib, but it does seem to use the API that I think is the most ergonomic across libraries I saw in Go (specifically, varargs for key values, and the ability to create subloggers using .With), so I guess it's nice most of the community will standardize around it.<p>If all goes well, you won't have different libraries using different loggers anymore, in some not too distant future, which should improve easy composability.
The new experimental fix for loop variable capture [0] is huge; this is the biggest footgun with the language in my experience.<p>I hope the experimental fix makes it into the next version of Go by default.<p>[0] <a href="https://github.com/golang/go/wiki/LoopvarExperiment">https://github.com/golang/go/wiki/LoopvarExperiment</a>
Nice, my push for actually using the sha256 instructions on amd64 finally got released. 3x-4x increase in hash speed on most x86 which is really nice for content addressable storage use cases like handling container images.
I enjoy Go so much. It is almost perfect language for getting things done, but I still can't understand some design choices.<p>Does someone knows why Go uses env variables (like GOOS and GOARCH) instead command line arguments?
Worth noting that the release announcement was written by Eli Bendersky, of <a href="https://eli.thegreenplace.net/" rel="nofollow noreferrer">https://eli.thegreenplace.net/</a> fame. It's a fantastic technical blog with literally decades of content.
These new packages, like slices and maps, were a long time coming. So glad it's finally here.<p>I cannot even begin to tell you how many different itemInSlice functions I've written over the years.
Overall, a release more for engineering than language. Even the new API's are mainly optimizations, and optimizations are netting ~10% (pretty good for an mature toolset).<p>The WASI preview shows Google is committing engineering resources to WASM, which could grow the community a touch.
A good first step for better WASM support, however it's currently incompatible with tinygo's WASM target.<p>For example, I'm working on a custom WASM host (non-browser) and have a tinygo WASM package with import bindings like this:<p><pre><code> //go:wasm-module rex
//export wait_for_event
func wait_for_event(timeout_usec uint32, o_event *uint32) bool
</code></pre>
Both these comment directives are tinygo-specific of course, and now Go has added its own third and different directive of course.<p>When I add Go's desired `//go:wasmimport rex wait_for_event` directive, it complains about the types `*uint32` and `bool` being unsupported. Tinygo supports these types just fine and does what is expected (converting the types to uint32). On the surface, I understand why Go complains about it, but it's such a trivial conversion to have the compiler convert them to `uint32` values without requiring the developer to use unsafe pointer conversion and other tricks.<p>Hopefully I can find a way to keep both tinyo and Go 1.21rc2 happy with the same codebase going forward and be able to switch between them to evaluate their different strengths and weaknesses.
Seems like a really substantial release to me. The new built in functions min, max, and clear are a bit surprising, even having followed the discussions around them. The perf improvements seem pretty great, I’m sure those will get much love here.<p>Personally, I’m most excited about log/slog and the experimental fix to loop variable shadowing. I’ve never worked in a language with a sane logging ecosystem, so I think slog will be a bit personally revolutionary. And the loop fix will allow me to delete a whole region of my brain. Pretty nice.
Really glad to see some of these new packages (sort, map, etc) making use of generics. Should reduce the need for a lot of helper functions.<p>Also really excited to see loop capture variables finally getting sorted out. It is a constant pain point with new devs, and I have no good answer when they ask "but WHY is it like this?"<p>More information about loop capture here for those interested <a href="https://github.com/golang/go/discussions/56010">https://github.com/golang/go/discussions/56010</a>
Nice - but hang on a second, I thought you cannot shadow language keywords in Go. So projects bumping to 1.21 in the future should be aware that you will run into compile time errors all of a sudden… doesn’t that actually break the compatibility promise?<p><pre><code> max := something()
</code></pre>
<a href="https://go.dev/doc/go1compat" rel="nofollow noreferrer">https://go.dev/doc/go1compat</a>
This is great, but why do I get the sense that Golang's development is so slow? Ex:<p>Java: We added structured concurrency and virtual threads!<p>Golang: We added a min function!<p>Most of the standard lib still doesn't properly support generics, and at this pace, it will be another 5 years at least before it does.
> New built-in functions: min, max and clear.<p>What a mistake.. reserved keywords are words I can no longer use for myself...<p>Zig does it better by requiring a prefix @ for most their builtin needs
Wait is this now heap allocating a value in every iteration of every loop? I hope that allocation is optimized out in every case where there isn't a closure over the loop variable?
really hope Go has something like MERN for node.js or Django for Python, so I can use it for ready-to-go backend framework. There are gin and echo etc, just not as widely adopted as MERN or Django.<p>in some of my use cases, I need make sure source code is fully protected, neither Node nor Django can do that well, Go will be perfect as it is compiled, however there is nothing like MERN or Django in Go(yet). Another option will be Java, but I do not know Java.
Wrote a blog explicitly asking for some of these changes last year:
<a href="https://www.lremes.com/posts/golang/" rel="nofollow noreferrer">https://www.lremes.com/posts/golang/</a><p>Nice to see their going in a good direction.