[Go 1.21](https://go.dev/doc/go1.21) has been released! For past releases, I wrote up my notes on what’s new in Go 1.18 ([part 1](/post/2021/golang-118-minor-features/), [part 2](/post/2022/golang-118-even-more-minor-features/)), [1.19](/post/2022/golang-119-new-features/), and 1.20 ([part 1](/post/2023/golang-120-language-changes/), [part 2](/post/2023/golang-120-arenas-errors-responsecontroller/), [part 3](/post/2023/golang-120-minor-features/)), but I thought I would sit this round of blogging out, in part because there have been [some](https://changelog.com/gotime/286) [good](https://www.sethvargo.com/things-im-excited-for-in-go-1-21/) [roundups](https://medium.com/lyonas/whats-new-in-go-1-21-a-comprehensive-notes-96017750b390) [of](https://www.dolthub.com/blog/2023-07-07-golang-1.21-release/) [what’s](https://lukas.zapletalovi.com/posts/2023/about-structured-logging-in-go121/) [new](https://antonz.org/go-1-21-builtins/) [elsewhere](https://double-trouble.dev/post/go-1-21/) already, and in part because I’ve been on family vacation until recently and haven’t had time to write much. However, I didn’t want to let 1.21 go totally by without talking about what I contributed, because if I don’t talk up my own contributions, who else will? - - - - The background to the first thing I worked on is that [@fnxpt](https://github.com/fnxpt) on Github [proposed](https://github.com/golang/go/issues/53747) adding a variation on [flag.Func](https://pkg.go.dev/flag#Func) to the flag package that would work even without an argument. To review, the flag package parses command line flags, like `myprogram -verbose -input file.txt -output out.txt`. Some flags have arguments (like `-input file.txt` or `-output out.txt`) and some do not (like `-verbose`). The flag package makes it pretty fast and easy to whip up a simple command line application that reads in flags. The `flag.Func` method lets you add a callback that gets called whenever a certain flag is present on the command line. For example, if `-input` were configued by `flag.Func`, it might add a callback that would use `os.Open` on whatever argument is after `-input`. I had previously [proposed and implemented flag.Func](/post/2020/add-func/) and had written my own [flagx.BoolFunc](https://pkg.go.dev/github.com/carlmjohnson/flagx#BoolFunc) in my personal flag utilities library, so when I saw that the proposal for flag.BoolFunc had been approved, I went ahead and did the implementation. It works [like this](https://pkg.go.dev/flag#example-BoolFunc): ```go flag.BoolFunc("log", "logs a dummy message", func(s string) error { fmt.Println("dummy message:", s) return nil }) ``` ``` $ myprogram -log dummy message: true $ myprogram -log=0 dummy message: 0 ``` Simple enough, but someone had to write it, so why not me? 😉 - - - - - Second, I want to talk about a featured that I helped _keep out_ of Go. During the planning for adding generics to Go, it was [proposed](https://github.com/golang/go/issues/45458) that there should be a constraints package to contain common generic type constraints, like `Ordered` or `Numeric`. The main sticking point for the package was the name. No one really loved the name “constraints” because it is too long. (Perhaps call it [c8s](https://kubernetes.io)?) [Other names were proposed](https://github.com/golang/go/issues/50348), but in the end, the decision was made to just [move the constraints package out of the standard library](https://github.com/golang/go/issues/50792) and into [golang.org/x/exp](http://golang.org/x/exp) to get experience using it before it was added into the standard library itself. Then after Go 1.18 came out, I made [my own counterproposal](https://github.com/golang/go/issues/52427): > Most of the remaining constraints after [#48424](https://github.com/golang/go/issues/48424) [a pre-generics proposal that made constraints shorter to type] are purely numeric: Complex, Float, Integer, Signed, Unsigned. They can all just be added to package math. Ordered is the exception because it also involves strings. It can be added to package sort. There's no longer any need for a top level constraints package. Well, my proposal wasn’t quite accepted as is, but I feel like I won the war because with Go 1.21 it’s clear: **There's no longer any need for a top level constraints package.** Go 1.21 adds a [slices package](https://pkg.go.dev/slices) and slices has `slices.Sort`, which in the exp version required [constraints.Ordered](https://pkg.go.dev/golang.org/x/exp@v0.0.0-20230807204917-050eac23e9de/constraints#Ordered). For the standard library, however, `slices.Sort` relies on [cmp.Ordered](https://pkg.go.dev/cmp#Ordered) in the brand new cmp package (not quite `sort.Ordered`, as I had proposed, but close enough). The numeric constraints haven’t been added anywhere in the standard library yet, but it’s clear that even if they do, it won’t be in a package called “constraints”. There’s a longstanding rule of thumb in Go [to avoid utility packages](https://dave.cheney.net/2019/01/08/avoid-package-names-like-base-util-or-common): > These packages contain an assortment of unrelated functions, as such their utility is hard to describe in terms of what the package _provides_. This often leads to a package’s name being derived from what the package _contains_—utilities. The proposed constraints package was going to be a utility package for type constraints: it contained type constraints, but there was no unity to the constraints it contained. The only thing all the constraints did that was the related was constraining generic types. I wrote in my issue, "'Constraints' is like 'utils' but for types. It's better to have something specific than a bunch of general stuff crammed in one place." Now the Go standard library has avoided adding it, and I'm going to take a least partial credit. 😉 - - - - So, that's what I worked on for this cycle: one addition and one non-addition. Please, enjoy using Go 1.21 with more func and without constraints.