It is interesting to see them add things like the "clear" function for maps and slices after suggesting to simply loop and delete each key one at a time for so long. Is this a result of the generics work that makes implementation easier vs. the extra work of making a new "magic" function (like "make", etc.)?
> It is interesting to see them add things like the "clear" function for maps and slices after suggesting to simply loop and delete each key one at a time for so long. Slowly walking back dogmatic positions is just how the Go team works. I say this as a person that wrote Go full time for a handful of years.
Go 1.21 Release Candidate
171–180 of 236 posts
Re: Go 1.21 Release Candidate
#172Earlier quoted context omitted.
> The slice in Go is more or less equivalent to &[] in Rust or std::span in C++. My understanding is, to use the Rust/C++ term, slices in Go are owned, but they are not in Rust or C++. That is, they're a pointer + length in the latter two, but a pointer, length, and capacity in Go.
The type in Go does not carry ownership information. It is not a useful distinction to say that slices are "owned" in Go.
I think the distinction is useful specifically because it explains why Go slices work differently than in at least those two languages.
Re: Go 1.21 Release Candidate
#173Loop variable capture is a foot-gun that in the last six years has cost me about 10-20 hours of my life. So happy to see that go. (Next on my list of foot-guns would be the default infinite network timeouts — in other words, your code works perfectly for 1-N months and then suddenly breaks in production. I always set timeouts now; there’s basically no downside)
Interesting to see them changing course on some fundamental decisions made very early on. The slices *Func() functions use cmp() int instead of less() bool, which is a huge win in my book. Less was the Elegant yet bizarre choice — it often needs to be called twice, and isn’t as composable as cmp.
The slog package is much closer to the ecosystem consensus for logging. It’s very close to Uber’s zap, which we’re using now. The original log package was so minimal as to be basically useless. I wonder why they’re adding this now.
I’ve already written most of what’s in the slices and maps packages, but it’ll be nice to have blessed versions of those that have gone through much more API design rigor. I’ll be able to delete several hundred lines across our codebase.
What’s next? An http server that doesn’t force you to write huge amounts of boilerplate? Syntactic sugar for if err != nil? A blessed version of testify/assert? Maybe not, but I’m happy about these new additions.
Re: Go 1.21 Release Candidate
#174Really glad to see some of these new packages (sort, map, etc) making use of generics. Should reduce the need for a lot of helper functions. Also really excited to see loop capture variables finally getting sorted out. It is a constant pain point with new devs, and I have no good answer when they ask "but WHY is it like this?" More information about loop capture here for those interested https://github.com/golang/go/…
Because, historically, it's been like that all over, it's not just Go. For example, Python has the same loop variable reuse.
Probably comes from a time when compilers were a lot simpler, and all local variables were allocated stack space for the whole duration of the function call.
Re: Go 1.21 Release Candidate
#175Earlier quoted context omitted.
The type in Go does not carry ownership information. It is not a useful distinction to say that slices are "owned" in Go.
Types in C++ don’t carry ownership information inherently either, but they’re still thought of in these terms. I know Go doesn’t often use these terms, which is why I clarified. I think the distinction is useful specifically because it explains why Go slices work differently than in at least those two languages.
I have a particular axe to grind when it comes to the word “ownership” of objects in programming. In C++ and Rust there is a very natural sense of ownership in that the owner of an object is who may deallocate the object, and that ownership may be shared with std::shared_ptr in C++ or Rc / Arc in Rust. Ownership is such a useful concept in these languages because it is generally true that somebody must deallocate the object, and it must happen safely.
As a very natural consequence, people who spend long hours working in C++, Rust, C, or other similar languages start to associate, very closely, the notions of ownership and correctness. And indeed, ownership is broadly useful outside C++, Rust, and C. Even in a garbage-collected language like Java or Go, it is generally useful to have clear ownership. You don't modify objects that you don't own, or use objects outside their scope.
But occasionally, you come across a piece of code where ownership gets in the way. Perhaps some garbage-collected algorithm that transforms data with pointers going all over the place. It probably sounds like a mess, but that is not necessarily true either—it can be perfectly good, correct, readable code.
So while ownership is a useful concept for talking about specific pieces of Go code, or specific pieces of Java code, it is not applicable to all Go or Java code, and that’s fine. It’s kind of like talking about code in terms of functions—nearly every language on the planet makes heavy use of functions (or some equivalent), but it’s also true that code does not have to be organized in functions, and you will occasionally see code that does not use functions.
Re: Go 1.21 Release Candidate
#176This is great, but why do I get the sense that Golang's development is so slow? Ex: Java: We added structured concurrency and virtual threads! Golang: We added a min function! Most of the standard lib still doesn't properly support generics, and at this pace, it will be another 5 years at least before it does.
Tbh I don’t see most of the standard lib benefitting from generics. For example, json.Unmarshal wouldn’t be dramatically better with generics — in practice, I rarely see runtime errors where I passed the wrong kind of thing to that function.
I personally love the slow pace of go development. I love that I don’t need to refactor my code every year to take advantage of whatever new hotness they just added. The downside is that stuff that’s annoying now will be annoying forever (like those times when you want a more expressive type system), but I’m willing to live with that.
Re: Go 1.21 Release Candidate
#177Earlier quoted context omitted.
> It is interesting to see them add things like the "clear" function for maps and slices after suggesting to simply loop and delete each key one at a time for so long. Slowly walking back dogmatic positions is just how the Go team works. I say this as a person that wrote Go full time for a handful of years.
No, it's because a use case was discovered that the for loop approach can't handle: NaN keys.
Re: Go 1.21 Release Candidate
#178This is at least the biggest release since 1.18 with generics, possibly bigger. I’m excited because the changes demonstrate a transition from the traditional go philosophy of almost fanatical minimalism, to a more utilitarian approach. Loop variable capture is a foot-gun that in the last six years has cost me about 10-20 hours of my life. So happy to see that go. (Next on my list of foot-guns would be the default inf…
Re: Go 1.21 Release Candidate
#179Earlier quoted context omitted.
Regardless of how the compiler is optimising this, I 100% agree that the old behaviour is unexpected and it’s caught me at least once. Really happy to see this (until recently) unexpected change.
I don't actually use Go, but I have used many other languages where it is like the old behavior. I learned once that I have to build the closure correctly to get the value I want and know now to do it. Don't have any statistics on whether I made that mistake again, but anecdotally I can't remember a case where I have. In their analysis they have found a lot of cases with that mistake, though. So I guess fair enough.…
The only lesson to be learned here is that languages are different. But I think the new Go behaviour is more ergonomic.
Re: Go 1.21 Release Candidate
#180This is at least the biggest release since 1.18 with generics, possibly bigger. I’m excited because the changes demonstrate a transition from the traditional go philosophy of almost fanatical minimalism, to a more utilitarian approach. Loop variable capture is a foot-gun that in the last six years has cost me about 10-20 hours of my life. So happy to see that go. (Next on my list of foot-guns would be the default inf…