Description
What
Proposal #43651 is to add generics to the Go language. The proposal currently has 1223 likes and only 89 dislikes. Demand for generics was a top requested feature in the 2016, 2017, 2018, and 2019 Go developer survey results. There's a working go2go Playground for trying out the proposal. The type parameters proposal was the subject of a keynote talk at GopherCon 2020. This is a widely demanded feature from the Go community; it's not a niche feature like persistent memory or field tracking.
This proposal then is about allowing prototype compiler development of that feature to happen on the master branch. The new language functionality would be kept behind a compiler flag until both (1) #43651 is accepted and (2) the functionality is ready for end users.
Of course, if #43651 is accepted before this proposal, then this one becomes moot. Alternatively, should #43651 be rejected after this one is accepted, then the implementation support code should be backed out of master.
Rationale
We've already begun development for #43651 on the dev.typeparams branch, but keeping it in sync with master and dev.regabi has been very tedious. Within the last 2 months of development, we've had 20+ merges between branches. We had a failed merge that required resetting the development branches (#43147). We've had compiler engineers attempt and give up merges, because the conflicts were too difficult to resolve without more familiarity/time.
This tedium will likely decrease somewhat after Go 1.16 is released and dev.regabi merges back into master, but then there will also be changes happening elsewhere in the repo to keep up with (e.g., #42637 caused a lot of trybot flakes on both dev.regabi and dev.typeparams). Also, support for generics will continue requiring more pervasive changes that involve touching the backend. There are also other accepted Go language changes slated for Go 1.17 (e.g., #395, #19367, #38248, #40481) that will overlap in frontend areas.
It would ease cmd/compile development significantly if the compiler functionality in dev.typeparams could be merged into master and developed behind a feature flag. Feature flags are how we developed binary export (ae2f54a), SSA (c0740fe), package syntax's new parser (2ff4639), indexed export (ca2f85f), new escape analysis (97c4ad4), etc. (I'm sure there are others; these are just ones I'm personally familiar with.)
Additionally, dev.typeparams introduces a new go/types-based typechecker "types2". Even if we reject #43651, I think we want to adopt this new typechecker to replace the compiler's legacy typechecker ("typecheck"). And because generic support in types2 is already conditional behind a flag, removing generics support if #43651 is rejected would be no different than when we removed the old code any of the above features replaced.
Flag
As for how to spell the compiler flag, dev.typeparams currently uses -G
, but other spellings would be fine. The particular values assigned to it though are somewhat arbitrary, driven by development needs that no longer apply, so they should be revisited. I suggest -G=0
means use typecheck; -G=1
means use types2 w/o generics support; and -G=2
means use types2 w/ generics support. (I'm hopeful -G=1
can be the default for Go 1.17; then we can drop support for -G=0
for Go 1.18, which should make it easier to enable -G=2
by default. However, I'm not proposing either of these default changes at this time.)
It's been brought up that users might then use it and things could break. We currently provide users with compiler flags like -B
(disable bounds checking), -wb=false
(disable write barriers), and -d=disablenil
(disable nil checking), so users have ample opportunities for self-harm today already.
But moreover, I think we want users trying out features before they're fully ready. It's been helpful having users report regressions on dev.regabi (#43479, #43480, #43701, #43818), and at the end of release cycles we're always begging for users to try the betas and release candidates.
If really desired, we could put it behind GOEXPERIMENT=typeparams
with other features like field tracking and static lock ranking, which never went through the proposal process. But then I'd ask again for consideration of #42681.