Those are just the changes to the language! Many releases have none at all. Keep scrolling for a lot of improvements to the toolchain and standard library, including a couple security changes that might cause necessary behavior changes.
"The io/ioutil package has turned out to be a poorly defined and hard to understand collection of things. All functionality provided by the package has been moved to other packages. The io/ioutil package remains and will continue to work as before, but we encourage new code to use the new definitions in the io and os packages."
why does the stdlib need to adopt generics? That would break the Go1 promise. They would likely introduce new functions rather than changing existing ones. RE: what they did with the ioutil package
How far are we from Golang 2.0 RCs? Are they trying to exceed Scala 3's development cycle?
As much as I'd like to use a pragmatic language like golang, I can't live without generics (many folks feel the same way.) Feels like I'm better off learning Rust. Go's loss is Rust's gain.
You learn to work around the lack of generics quite easily. Sometimes this means having to write the same code a few times. But if I look at our entire codebase you're looking at something that impacts less than 1%. I think for most projects the lack of generics is not a major issue.
For 7 years I felt that way. That yeah, generics might be nice-to-have in Go, but if you were really sweating it that it meant you were still thinking in Java instead of Go. But then I switched teams at work and...
> Me: Nothing has ever made me want generics in Go the way that the telepresence2 codebase has made me want generics in Go.
> CTO: Is this because of the problem domain or the incidental structure of the code?
> Me: I'm honestly not sure. I want to say the incidental structure of the code, but I'm not sure how else I'd structure it.
I implemented codegen/template based generics, but eagerly await being able to replace that with actual generics in Go 1.18.
So, I guess the lesson is that it's easy to write off it off when it's someone else having the problem?
The funny thing is that in 30 years there will be a new generation of people convinced that nobody needs generics because they happened not to need them in their command line tool replacing a bash script that has grown too large for comfort.
In 2017[1] it was decided that the "Go 2" project would be done incrementally adding features in Go 1.x releases, as long as those features can be added in backward-compatible ways, and there will likely only be a actual 2.x release if they need to make backward incompatible changes:
> Once all the backwards-compatible work is done, say in Go 1.20, then we can make the backwards-incompatible changes in Go 2.0. If there turn out to be no backwards-incompatible changes, maybe we just declare that Go 1.20 is Go 2.0. [1]
With that, they developed a formal language-change proposal and acceptance process, and the Go 2 proposals transitioned from being pie in the sky ideas to concrete proposals, and a number of proposals for "go2" features were selected[2] to be included in 1.13. And so in September 2019, Go 1.13 became the first "go2" release[3], the first release since 2012 to include significant language changes.
And so we've been seeing language changes land incrementally in releases for the last several years now, rather than waiting for a "big bang" 2.0 release.
# Development cycle
Go does a release every 6 months, in February and in August. ("But above you said 1.13 was in September!" Yes, it slipped from August to September 3rd.)
# Generics
Generics[4] are currently slated to be in Go 1.18 (February 2022).[5]
> As much as I'd like to use a pragmatic language like golang, I can't live without generics (many folks feel the same way.) Feels like I'm better off learning Rust. Go's loss is Rust's gain.
You can usually have "generics" by way of code generation, or losing type safety. Both aren't perfect but they still work. I wonder, what do you use generics for? Maybe Go isn't suited for that type of work in general.
> Feels like I'm better off learning Rust. Go's loss is Rust's gain.
Or just Java, Go isn't just competing with Rust. Again, that will depend on your problem space.
There aren't many productive language discussions that include sentences like "Blub's loss is Floop's gain". If you want to learn Rust, go learn Rust. We call them "languages", but they're just tools we use to solve problems. Use the one that makes sense for you. We use both Blub and Floop; it works out fine.
I feel a bit differently about it. Learning Rust is a longer process, but after it's done, it can do everything better than Go (faster, safer, less code). It can also do things that Go cannot.
People choose Go because they are incapable of making that initial investment. Maybe they know too little and can't wrap their head around the necessary concepts (a CS curricilum should teach one everything that's necessary though), or they know too much and they don't want to learn new things anymore.
I see these programmers as vunerable and confused, and easy to take advantage of. They need something they can feel comfortable and proficient in, and Go provides that. Unfortunately Go is also tied to one corporation and its internal politics.
And so the quality of life od these poor souls is being sacrificed because of someone's strongheaded opinions within their organization. The tragedy is that the Go community is prone to take the words of the Go team as the words of God. And they adapt their mindset to match. So they take on the arguments of the Go developers, and start using them, not realizing that in reality they're arguing against themselves, their comfort and productivity.
Generics, algebraic data types, type inference for lambdas, namespaces, immutability, non-nil pointers, tuples, better error handling, all of these things would improve Go user's lives, even if they don't realize it themselves. But it would be a hassle for Google to add them.
You're being absurdly condescending. Maybe those people aren't lost, but you're just not seeing something they do, or are used to completely different use cases?
I've used and understood most if not all of the languages you might have in mind as being "superior" to Go, Rust wasn't very difficult other than the initial 2 weeks warmup. I've used it for a few months on a side project. It's fun.
And yet I choose to use Go in my day to day 95% of the time.
Go is an insanely practical language. It's also a very productive one, mostly thanks to the ecosystem and people being very practically-oriented instead of bikeshedding on every little detail. Depending on your area of work, it has an extensive ecosystem of libraries too.
And most of all, it's got the best asynchronicity model I've so far had the pleasure to work with. You can see more about this in my recent comment[0].
Yes, it lacks some features, but it's getting there. And wether I agree with the final form of those features or not, I'm happy they're not being rushed.
And yes, like all tools, for some use cases it is a terrible choice.
You just didn't get what I was getting at. Go as a language is fine, and it's OK to like it and to use it.
The problem is that it can't get better, and the obvious issues can't get fixed because any improvements to the language are mired in Google's infighting process.
There were internal voices pointing out a need for generics 10 _years_ ago.
Instead, their PR messaging is convincing people that actually they don't need generics, instead of admitting that the language is incomplete.
My biggest issue with Go is mostly generics really, everything else I can live with it.
Rust's killer domain are kernels, device drivers, high integrity computing, GPGPU, basically domains where having any sort of GC is a hard sale, even if already proven otherwise, or just considered too risky due to timing constraints.
> If a module specifies go 1.17 or higher in its go.mod file, its transitive requirements are now loaded lazily, avoiding the need to download or read go.mod files for otherwise-irrelevant dependencies. To support lazy loading, in Go 1.17 modules the go command maintains explicit requirements in the go.mod file for every dependency that provides any package transitively imported by any package or test within the module. See the design document for more detail.
Wait, does this mean we can import things that themselves import kubernetes without also having to include this huge list of overrides [0] due to the huge list of v0.0.0 imports that k8s then overrides?
Or is that going to take other changes... (like fixing whatever makes k8s import + override v0.0.0)
> like fixing whatever makes k8s import + override v0.0.0
What needs fixing is the kubernetes.git release process.
kubernetes.git/go.mod "overrides" v0.0.0 not with another version (as you do), but with a local directory, because the sources-of-truth for each of those are the kubernetes.git/staging/XXX/ directories. Because of this, if you're working in kubernetes.git the version number never actually matters, so they just leave it with a dummy v0.0.0. But it does matter if you want to import kubernetes.git!
If you have nested Go modules in one repo like that, the thing to do to keep your importers happy is that whenever you do a release, you `go mod edit -require=NESTED_MODULE@VERSION` to bump the version number to the one you're about to release. This is what we do in Telepresence[1], if only we could get the Kubernetes folks to do it too...
> Note that the new conversion from slice to array pointer is the first case in which a type conversion can panic at run time. Analysis tools that assume type conversions can never panic should be updated to consider this possibility.
I'm not worried about updating tools, I'm worried about updating humans that assume type conversions can never panic at run time. This change feels like adding a substantial foot-gun.
> The P521 curve implementation has been rewritten using code generated by the fiat-crypto project, which is based on a formally-verified model of the arithmetic operations. It is now constant-time and three times faster on amd64 and arm64. The observable behavior has not otherwise changed.
This is exciting to see formally-verified Coq code being pulled into Go.
42 comments
[ 1.7 ms ] story [ 70.7 ms ] threadhttps://mobile.twitter.com/golang/status/1414721238224838666
EDIT: TLS clients, not server.
Looks like a pretty minor release.
Go 1.17 includes three small enhancements to the language: Conversions from slice to array pointer, unsafe.Add, unsafe.Slice
Under the hood changing calling conventions is seriously large rework of the compiler and runtime.
They'll be introduced in a backwards compatible way.
Generally, adding features does not break backwards compatibility. Note that ioutil was depreciated while it is unlikely to ever be removed
It will never be removed, thankfully.
https://github.com/golang/go/issues/16736
As much as I'd like to use a pragmatic language like golang, I can't live without generics (many folks feel the same way.) Feels like I'm better off learning Rust. Go's loss is Rust's gain.
> Me: Nothing has ever made me want generics in Go the way that the telepresence2 codebase has made me want generics in Go.
> CTO: Is this because of the problem domain or the incidental structure of the code?
> Me: I'm honestly not sure. I want to say the incidental structure of the code, but I'm not sure how else I'd structure it.
I implemented codegen/template based generics, but eagerly await being able to replace that with actual generics in Go 1.18.
So, I guess the lesson is that it's easy to write off it off when it's someone else having the problem?
In 2002, Visual Studio T4 was used for generating .NET code shortly after it was introduced.
In 2005, Eclipse EMF was used for generating Java code, eventually Java 5 made that unnecessary.
As you see, that is a path well known for the last 30 years.
Eagerly waiting for Go 1.18, even with CLU like generics.
In 2017[1] it was decided that the "Go 2" project would be done incrementally adding features in Go 1.x releases, as long as those features can be added in backward-compatible ways, and there will likely only be a actual 2.x release if they need to make backward incompatible changes:
> Once all the backwards-compatible work is done, say in Go 1.20, then we can make the backwards-incompatible changes in Go 2.0. If there turn out to be no backwards-incompatible changes, maybe we just declare that Go 1.20 is Go 2.0. [1]
With that, they developed a formal language-change proposal and acceptance process, and the Go 2 proposals transitioned from being pie in the sky ideas to concrete proposals, and a number of proposals for "go2" features were selected[2] to be included in 1.13. And so in September 2019, Go 1.13 became the first "go2" release[3], the first release since 2012 to include significant language changes.
And so we've been seeing language changes land incrementally in releases for the last several years now, rather than waiting for a "big bang" 2.0 release.
# Development cycle
Go does a release every 6 months, in February and in August. ("But above you said 1.13 was in September!" Yes, it slipped from August to September 3rd.)
# Generics
Generics[4] are currently slated to be in Go 1.18 (February 2022).[5]
[1]: https://blog.golang.org/toward-go2
[2]: https://blog.golang.org/go2-here-we-come
[3]: https://blog.golang.org/go2-next-steps
[4]: https://github.com/golang/go/issues/43651
[5]: https://blog.golang.org/generics-proposal
You can usually have "generics" by way of code generation, or losing type safety. Both aren't perfect but they still work. I wonder, what do you use generics for? Maybe Go isn't suited for that type of work in general.
> Feels like I'm better off learning Rust. Go's loss is Rust's gain.
Or just Java, Go isn't just competing with Rust. Again, that will depend on your problem space.
Check if an element is contained in a slice is the textbook example.
https://tinygo.org/
https://www.f-secure.com/en/consulting/foundry/usb-armory
Naturally Rust remains an option for the use cases where GC, for whatever technical reason, is indeed not possible.
People choose Go because they are incapable of making that initial investment. Maybe they know too little and can't wrap their head around the necessary concepts (a CS curricilum should teach one everything that's necessary though), or they know too much and they don't want to learn new things anymore.
I see these programmers as vunerable and confused, and easy to take advantage of. They need something they can feel comfortable and proficient in, and Go provides that. Unfortunately Go is also tied to one corporation and its internal politics.
And so the quality of life od these poor souls is being sacrificed because of someone's strongheaded opinions within their organization. The tragedy is that the Go community is prone to take the words of the Go team as the words of God. And they adapt their mindset to match. So they take on the arguments of the Go developers, and start using them, not realizing that in reality they're arguing against themselves, their comfort and productivity.
Generics, algebraic data types, type inference for lambdas, namespaces, immutability, non-nil pointers, tuples, better error handling, all of these things would improve Go user's lives, even if they don't realize it themselves. But it would be a hassle for Google to add them.
I've used and understood most if not all of the languages you might have in mind as being "superior" to Go, Rust wasn't very difficult other than the initial 2 weeks warmup. I've used it for a few months on a side project. It's fun.
And yet I choose to use Go in my day to day 95% of the time.
Go is an insanely practical language. It's also a very productive one, mostly thanks to the ecosystem and people being very practically-oriented instead of bikeshedding on every little detail. Depending on your area of work, it has an extensive ecosystem of libraries too.
And most of all, it's got the best asynchronicity model I've so far had the pleasure to work with. You can see more about this in my recent comment[0].
Yes, it lacks some features, but it's getting there. And wether I agree with the final form of those features or not, I'm happy they're not being rushed.
And yes, like all tools, for some use cases it is a terrible choice.
[0]: https://news.ycombinator.com/item?id=27545031
The problem is that it can't get better, and the obvious issues can't get fixed because any improvements to the language are mired in Google's infighting process.
There were internal voices pointing out a need for generics 10 _years_ ago.
Instead, their PR messaging is convincing people that actually they don't need generics, instead of admitting that the language is incomplete.
https://golang.org/doc/faq#generics
Rust's killer domain are kernels, device drivers, high integrity computing, GPGPU, basically domains where having any sort of GC is a hard sale, even if already proven otherwise, or just considered too risky due to timing constraints.
Language features alone don't sell products.
Wait, does this mean we can import things that themselves import kubernetes without also having to include this huge list of overrides [0] due to the huge list of v0.0.0 imports that k8s then overrides?
Or is that going to take other changes... (like fixing whatever makes k8s import + override v0.0.0)
0: https://github.com/replicatedhq/kots/blob/v1.47.0/go.mod#L11...
1: https://github.com/kubernetes/kubernetes/blob/v1.21.2/go.mod...
What needs fixing is the kubernetes.git release process.
kubernetes.git/go.mod "overrides" v0.0.0 not with another version (as you do), but with a local directory, because the sources-of-truth for each of those are the kubernetes.git/staging/XXX/ directories. Because of this, if you're working in kubernetes.git the version number never actually matters, so they just leave it with a dummy v0.0.0. But it does matter if you want to import kubernetes.git!
If you have nested Go modules in one repo like that, the thing to do to keep your importers happy is that whenever you do a release, you `go mod edit -require=NESTED_MODULE@VERSION` to bump the version number to the one you're about to release. This is what we do in Telepresence[1], if only we could get the Kubernetes folks to do it too...
[1]: https://github.com/telepresenceio/telepresence/blob/v2.3.4/b...
> Note that the new conversion from slice to array pointer is the first case in which a type conversion can panic at run time. Analysis tools that assume type conversions can never panic should be updated to consider this possibility.
I'm not worried about updating tools, I'm worried about updating humans that assume type conversions can never panic at run time. This change feels like adding a substantial foot-gun.
This is exciting to see formally-verified Coq code being pulled into Go.
https://github.com/mit-plv/fiat-crypto