Update Go version to the latest one?

Hi.

For some reason, exercises are still on go 1.18:
Sourcegraph search

Can we update to the latest(1.21.6) ?

There are a number of additions to the standard library since 1.18, so it is better for students to pick up those new features, right?

Also, 1.22 will include some new features, like range over int, loopvar sharing, etc.

So students should get access to those features without jumping through extra hoops(updating version in go.mod)

Also, 1.18 is not a supported version Release History - The Go Programming Language

See also Update go track version 1.21.1

There are a few things to clarify here.

Currently the test runner is on 1.21.1 (see here), which is the latest major version of Go. This means that code that uses the most recent things in the standard library will work as long as those standard library modules don’t use language features introduced between the current go.mod version (1.18) and 1.21.

There’s a key takeaway here: the go.mod version doesn’t affect which modules of the standard library you can use, as long as the new introductions to the standard library don’t use language features introduced meanwhile. This means that if you are concerned with using new things in the standard library, you can just use them right away with the current Exercism setup and it’ll likely just work.

If it doesn’t work, means that those new introductions to the standard library use new features. If that’s the case, you can just bump the version in the go.mod (as long it is less or equal than the go version we are using on the test runner) and submit the updated go.mod along with the exercise files.

Since the go.mod version only limits new language features and historically Go has seen little language features introduced over time, there was never a big reason for us to constantly update the go.mod version. Currently it is on 1.18 because that’s the version generics were introduced, and we considered that an important language feature. There’s also a fact that until a few months ago, changing the go.mod file would cause every Go solution to run on Exercism, which caused an outage before. There’s also the fact that some students try Go and the Exercism track, give up on Go for some time and then come back a few months later. If we aggressively update the go.mod file to always be on the lastest version of Go, we potentially force all those students to update their local Go version too (in case they are using the cli), which can be frustrating, specially if they are just trying Go more causally.

But I realize the situation is changing. Go is introducing new language features more aggressively, which means there’s more pressure on us to also keep the go.mod version more up-to-date. We also now have a way to make an update to the go.mod version and not re-run all solutions, so that’s no longer a problem.

The argument of go 1.18 being no longer supported is a good one, and we probably should at least keep the go.mod version in the oldest version that is supported.

When Go 1.22 is released, we’ll update the test runner to run on Go 1.22 and update all the go.mod versions to be on 1.20, which will be the oldest supported version then.

1 Like

Hi, Andres. Thanks for taking the time to reply!

There were some changes in the meaning of go directive starting with go.121, that I think is worth reading:
go.dev/blog/compat
go.dev/blog/toolchain
go.dev/ref/mod#go-mod-file-go

At go 1.21 or higher:

    The go line declares a required minimum version of Go to use with this module.
    The go line must be greater than or equal to the go line of all dependencies.
    The go command no longer attempts to maintain compatibility with the previous older version of Go.
    The go command is more careful about keeping checksums of go.mod files in the go.sum file.

There’s a key takeaway here: the go.mod version doesn’t affect which modules of the standard library you can use, as long as the new introductions to the standard library don’t use language features introduced meanwhile.

Oh, somehow I thought that I tired to use slices package locally and it did not work. I just re-verified, and it does work if my version of go is 1.21, even go 1.18 is specified in go.mod.

Your plan for 1.22 is very reasonable, except that I would update to 1.22 at that time, since loopvar thing is significant enough that I think it would be better to not have discrepancies between test-runner and local environment that people have.
But if you do decide on an older version in go.mod, per release policy linked above,
when 1.22 is released it is 1.21 which will be the latest supported version at that point.
But honestly, I do not see benefits in updating to something that is not the latest. Update is happening anyway, so with Go’s awesome backward compatibility, better to just update to the latest at that point.

Even if the test runner is on Go 1.22 and students’ local environment aren’t, loopvars will still behave the same in both environments, since the new behavior only applies if go.mod declares Go 1.22:

To ensure backwards compatibility with existing code, the new semantics will only apply in packages contained in modules that declare go 1.22 or later in their go.mod files. This per-module decision provides developer control of a gradual update to the new semantics throughout a codebase. It is also possible to use //go:build lines to control the decision on a per-file basis.

Source: Fixing For Loops in Go 1.22 - The Go Programming Language

Since the go version in the go.mod files won’t be in 1.22, runs in both the local environments and in the test runner will have the old behavior. Note that students can still opt-in in the new behavior by updating and submitting the go.mod file with version 1.22.

Right, we probably should consider updating the go.mod version to 1.21, but see below some reasons why we might want to be more forgiving than that.

Go’s backwards compatibility does mean that we can upgrade without worrying about changing the code in the exercises.

The main concern is is about forcing students to be up-to-date with no need, specially because like you posted, after go 1.21, it does declare a minimum Go version,. Imagine Go 1.22 is released tomorrow and we update the test runner and all the go.mod files to 1.22. This means that people that have Go 1.21 (which is probably the vast majority at that point) will be forced to upgrade to 1.22 just to use exercism. There’s no reason for that as there’s no major benefit in learning Go in 1.22 vs Go 1.21.

It’s not good to force people to be on the latest version of Go, for several reasons:

  • Some people like to install Go via their package manager, which might be several Go versions behind. On Linux, package managers are known to be a few versions behind, and those versions might be perfectly fine to learn Go. As an example, Ubuntu has 2 LTS at the moment, and the latest ships with Go 1.18 on their repos, despite 1.21 being the current one. On mac, Homebrew tries to be up-to-date with the latest Go version, but even Homebrew sometimes can take weeks to update the Go version they use, depending on the complexity of the release.
  • Other people might have installed Go some time ago and now they are back to it. Unless they are using a release that’s really old, they shouldn’t feel the need to upgrade, specially because they might not care about Go that much at that point and are still experimenting with it.

This is to say that forcing people to be on the latest version is not a good idea.

However, we do want to support people that do want to be on the latest version of Go. Like you said, Go has awesome backwards compatibility and people are encouraged to update as soon as possible. I believe most Go users update more often than if it was another language. But those people are also supported in Exercism today! We can have the test-runner on the latest version of Go, which means students can not only take advantage of the most recent stdlib, but they also can take advantage of the most recent language features if they update the Go version and submit their go.mod together with the solution.

As far as I see it, we gain very little by updating the go.mod Go version fiercely, and since Go 1.21 it will in fact set a minimum version for people to use it. Before it was ok to use an older version of Go on a module that declared a higher version of Go, as long as the language didn’t change between those versions. But since it now sets a minimum version, we should be even more careful. And that’s ok to be careful, that way we support people that are on slightly older versions of Go.

But it’s also really important we support people who want to be up-to-date, and we do that by upgrading the test-runner. With the version in go.mod, we want to give some guidance about what is the minimum version acceptable to use Exercism. While we want that version to also be as high as possible to have the default experience (without students changing their go.mod) be up-to-date, it’s hard to do that without breaking someone’s workflow and the more aggressively we update it, the more users workflows’ we risk to break.

3 Likes

Thanks, André.
Ok, got it. I will update go.mod in exercises locally before submitting.

Now that go1.22.0 is released, all these places(that do not include go.mod in exercises) could be updated?

[https://sourcegraph.com/search?q=context:global+%5Ego%5Cs%2B1.*+repo:github.com/exercism/go.*+count:all+-path:%5Eexercises/.*%24+&patternType=regexp&sm=1](https://context:global ^go\s+1.* repo:github.com/exercism/go.* count:all -path:^exercises/.*$ )

[https://sourcegraph.com/search?q=context:global+golang:+repo:github.com/exercism/go.*+count:all&patternType=regexp&sm=1](https://context:global golang: repo:github.com/exercism/go.* count:all)

In theory yes, we can update to Go 1.22. We usually run some tests on the test runner itself and depending on how those tests go, we will upgrade it.

When I submit go.mod with 1.22 in it, I get the following error:

image

Yes, that is because our tooling has not yet been updated (see comment from @andrerfcsantos).