InfoQ Homepage News Keeping Go "Boring" in Go 1.21: How Google Grants Backward Compatibility
Keeping Go "Boring" in Go 1.21: How Google Grants Backward Compatibility
Aug 18, 2023 2 min read
Write for InfoQ
Feed your curiosity. Help 550k+ globalsenior developers
each month stay ahead.Get in touch
In a recent article, Google engineer Russ Cox detailed what Google does to make sure each new Go release honors Go's backward-compatibility guarantee. This includes generalizing GODEBUG in Go 1.21 to cover even subtle incompatibility cases.
Introduced in Go 1, Go's backward compatibility guarantee ensures all correct Go programs will continue to work with future releases of the language. As Cox explains, this goal entails two major efforts: checking that each API change does not break anything and extensive testing to catch subtler incompatibility cases.
While the idea of checking API changes to prevent any breaking change from entering a new release may sound obvious, Cox also describes a number of cases where testing is the way to go:
The most effective way to find unexpected incompatibilities is to run existing tests against the development version of the next Go release. We test the development version of Go against all of Google’s internal Go code on a rolling basis. When tests are passing, we install that commit as Google’s production Go toolchain.
The examples provided by Cox fall into a few distinct categories, including changing the precision of the time.Now() library function, output or input changes, and protocol changes. There are cases, though, where a breaking change is brought by an important new features that must make it into the language, such as HTTP/2 support in Go 1.6 or SHA1 deprecation in Go 1.18.
To handle this kind of cases, Go provided a specific feature in release 1.6, the GODEBUG environment variable, which could be used to disable HTTP/2 for specific modules. In Go 1.21, Cox says, the GODEBUG mechanism has been extended and formalized.
Instead of using an environment variable, Go 1.21 uses a go:debug setting that can be specified in a package's main. This works in combination with the Go version listed in a module's go.mod file, so that each given Go version will have a default behavior that ensures compatibility on a feature-by-feature basis, while go:debug may be used to override it. For example, given that Go 1.21 changes panic(nil) behavior, developers may want to upgrade their toolchain to Go 1.21 but keep the old behavior. This is possible by overriding the version-specific go:debug setting by using:
//go:debug panicnil=1
According to Cox, this lets every new version of Go be the best implementation of older versions, fixing bugs while preserving backward-compatibility even in the face of important breaking changes.
Cox's article spun quite an interesting conversation on Hacker News, mostly on the relative merit of granting backwards compatibility in a language, versus introducing a new non-backward compatible version, as it happened in Python when going from Python 2 to Python 3; and comparing the approach taken by Go versus those taken by Java, C++, and .NT languages.
This content is in the Google topic
Related Topics:
-
Related Editorial
-
Related Sponsors
-
Popular across InfoQ
-
AWS Introduces EC2 Instance Attestation
-
Paper2Agent Converts Scientific Papers into Interactive AI Agents
-
AWS Launches Amazon Quick Suite, an Agentic AI Workspace
-
Google Introduces LLM-Evalkit to Bring Order and Metrics to Prompt Engineering
-
Java News Roundup: OpenJDK, Spring RCs, Jakarta EE, Payara Platform, WildFly, Testcontainers
-
Cloud and DevOps InfoQ Trends Report 2025
-
Related Content
The InfoQ Newsletter
A round-up of last week’s content on InfoQ sent out every Tuesday. Join a community of over 250,000 senior developers. View an example