Description
At this time, the Go distribution uses versions that look like this:
go1
go1.12
go1.12.5
go1.11beta1
go1.11rc2
Those version strings are used both in the output of go version
command, and as tag names in the source code repository.
Semantically, each version encodes a major, minor, and patch component, as well as optional pre-release metadata. However, the exact version string differs from semantic versions as defined by Semantic Versioning 2.0.0 specification in the following ways:
Differences
- If a trailing version component is zero, it's omitted rather than preserved.
- The second version component is referred to as "major version" rather than "minor version", and the third version component is referred to as "minor version" rather than "patch version". (For example, see https://github.com/golang/go/wiki/MinorReleases which by semver standard should be talking about patch versions, not minor versions.)
- Pre-release versions are denoted by appending a label immediately following a minor version, rather than by appending a hyphen and a series of dot separated identifiers immediately following the patch version.
4. The prefix is "go" rather than "v".
Go's current version strings are nice-looking and familiar, and this scheme was created before the existence and proliferation of https://semver.org. However, there are some disadvantages compared to following semver:
-
When someone talks about a "minor release" of Go, it's sometimes hard to know if they mean "x.Y.z" minor, or "x.y.Z" minor.
For people who are familiar with semver, it's difficult to refer versions such as 1.12.6 as "minor releases" because semver refers to the increased version component as "patch", and it's hard to know if the target audience will understand what you actually meant.
Following semver conventions, being as widespread as it is today, makes it possible to refer to all 3 version components without ambiguity or confusion.
-
Omitting the trailing version component makes it difficult to have clear conversation about those versions of Go releases.
For example, when someone says "I was able to reproduce the problem with go1.12", it's hard to tell if they mean it happens only the exact version
go1.12[.0]
only, or if they mean any patch version, including go1.12, go.1.12.1, go1.12.2, go1.12.3, etc.Similarly, it's hard to refer to the initial release version with a trailing zero version component. It can be temping to explicitly say "try it with go1.12.0" in order to be clear you mean that exact version and not any other.
-
Modules have adopted semver, and many people are familiar with semver. Right now, the Go project uses two different version string schemes. By adopting semver for Go release versions, we can reduce it from two schemes to just one scheme. It's simpler, more consistent and fewer things for users to learn and keep in their head.
Performing any change to the existing version scheme has transitional costs. However, I think the medium- and long-term benefits will outweigh the costs by a wide enough margin to consider this.
This proposal is to consider changing the Go release version format to match that of Go module versions, which is semver-compliant. Specifically, the trailing zero version components should always be included, the "go" prefix changed to "v", and beta/RC pre-release suffixes represented in a way that satisfies semver.
The proposed version strings can look like this:
go2.0.0
go2.12.0
go2.12.5
go2.11.0-beta.1
go2.11.0-rc.2
Update on 2023-03-01: withdrew the suggestion to change the "go" prefix to "v". See #32450 (comment) for my rationale.