The Go team has released Go 1.21, including three new built-in functions and a preview of a feature which changes the semantics of loop variables, addressing one of the most common causes of bugs in Go code.
The new built-in functions are min and max, which return the smallest or largest of a set of ordered types, and clear, which deletes or zeroes out all the elements in a map, slice or type parameter. In Go, a map is an unordered group of elements of one type, and a slice is a segment of an array.
Type inference has been improved in this version. In addition, the Go compiler has been rebuilt with PGO (Profile Guided Optimization), and builds Go programs two to four percent faster.
Go also has a new “experimental port” for WASI (WebAssembly System Interface). Go already has an option to compile to WebAssembly (WASM) for use in the browser, but until now did not support it for running outside the browser. The new feature means that Go applications could run as WASM in containers or on platforms such as Cloudflare workers. According to the project’s GitHub page, “for Go to remain relevant in a hypothetical world where this becomes a significant part of software delivery, it must support compiling code to the Wasm binary format and the WASI syscall API.”
Another key change addresses what the team calls “one of the most common gotchas of Go programming.” This is where loop variables are used in closures, or a loop variable address is assigned to another variable and used outside the loop. In Go, “the loop iterator variable is a single variable that takes different values in each loop iteration. This is very efficient, but might lead to unintended behavior when used incorrectly,” states a guide to Common Mistakes.
The LoopvarExperiment is a proposed fix that makes loop variables a different instance of the variable on each iteration. According to the team, the loop variable problem “hits all Go programmers” and the description highlights an example where the Let’s Encrypt developers, despite being aware of the issue, introduced a bug in their code that resulted in “over 3 million improperly-issued certificates”.
The snag is that the fix itself could break code that depends on the old behavior. That said, the team reckons that this “almost never” happens in the real world. Go was originally developed by Google, and the loopvar fix was tested against Google’s own code. “Testing on Google’s codebase found many tests were fixed. It also identified some buggy tests incorrectly passing due to bad interactions between loop variables and t.Parallel … we rewrote those tests to correct them,” said the team.
Despite this fix being experimental, “Google has been running with the new loop semantics applied to all for loops in the standard production toolchain since early May 2023 with not a single reported problem (and many cheers),” the description adds. More background to Google’s experience is here.
Now that 1.21 is out, other Go developers can do the same, but only by setting the environment variable GOEXPERIMENT=loopvar before installing, building or testing the code.