The [first release candidate for Go 1.22 is out](https://go.dev/dl/#unstable), which means it’s almost time for the final release and it is time for me to blog about what I worked on [this cycle](https://go.dev/wiki/Go-Release-Cycle). As usual, my contributions were small, but they were mine, so I’m going to talk about them from a behind-the-scenes perspective. First up is [reflect.TypeFor](https://pkg.go.dev/reflect@master#TypeFor). Here is the entire function: ```go // TypeFor returns the [Type] that represents the type argument T. func TypeFor[T any]() Type { return TypeOf((*T)(nil)).Elem() } ``` Pretty simple! The test code was about ten times longer than the actual function itself. The use of this function is when you want to create a `reflect.Type` object for a certain type, like `var intType = reflect.TypeFor[int]()` or `var errorType = reflect.TypeFor[error]()`. The [proposal to add this to the reflect package](https://github.com/golang/go/issues/60088) was opened by [Josh Bleecher Snyder](https://commaok.xyz). It marks yet another step in the ongoing march of generics through the standard library. The hardest part of this proposal was probably coming up with the right name for the function. `reflect.TypeOf` would be the most natural name for the function, but it’s [already taken](https://pkg.go.dev/reflect#TypeOf) by the existing function for creating a `reflect.Type` object. Alternatives considered include: - `StaticTypeOf` - `MakeType` - `TypeOfT` - `TypeFrom` - `GetType` - `AsType` - `ToType` - `NewType` - `TheType` - `Types` - `ConstantType` - `T` Naming things remains one of [the two hard problems in computer science](https://martinfowler.com/bliki/TwoHardThings.html). I [tossed out](https://github.com/golang/go/issues/60088#issuecomment-1555209904) the winning name, but at that point we were just going through a list of all possible adjectives and prepositions, so someone was going to hit on `TypeFor` eventually. I am, in general, opposed to the “[useless use](https://porkmail.org/era/unix/award) of generics” in which a generic function is used even when it doesn’t add any type safety and has no or minimal length savings. For example, making [a generic version of `json.Marshal`](https://github.com/golang/go/issues/59053) would be a useless use of generics because it doesn’t actually add any type safety. However, in this case, the right way to build a `reflect.Type` for an interface is fairly obscure, so I think it was worth adding. The issue goes back to the [First Law of Reflection](https://go.dev/blog/laws-of-reflection) in Go: "Reflection goes from interface value to reflection object." When you call `reflect.TypeOf(0)`, you get what you expect: a `reflect.Type` object for the type `int`. But if you call `reflect.TypeOf(err)` you may be surprised by what you get. Instead of getting an object containing the type `error`, you get an object with the underlying concrete type of `err`. That is because `error` is an interface value, and when you call a function in Go, interface parameters of functions are converted as needed, so the error interface is lost and only the concrete value is visible to `reflect.TypeOf`. Worse, if `err` is nil, you get a nil back from `reflect.TypeOf`. [Chris Siebenmann](https://utcc.utoronto.ca/~cks/space/blog/) wrote [a good explanation](https://utcc.utoronto.ca/~cks/space/blog/programming/Go122ReflectTypeFor) of what’s going on and how to work around it: > Because `reflect.TypeOf()` is passed an ‘`interface{}`’ (these days also known as ‘`any`’), it can't directly give you the [reflect.Type](https://pkg.go.dev/reflect@master#Type) of an interface, because that interface type will be lost when it's converted to ‘`interface{}`’. Instead `reflect.TypeOf()` returns the underlying non-interface type (or nil). [As we've seen in the context of '`nil`' being only sort of typed](https://utcc.utoronto.ca/~cks/space/blog/programming/GoNilIsTypedSortOf), to get around this you must pass a pointer to the interface (well, a value of the interface), get back the type 'pointer to ', and then [dereference](https://pkg.go.dev/reflect#Type) to the original type through reflect again… Before Go 1.22, the solution if you wanted to create `reflect.Type` for an interface was to call `reflect.TypeOf((*TheInterface)(nil)).Elem()`. This worked, but it was not very intuitive. I know I struggled to figure it out in my own code that uses the reflect package. When `reflect.TypeFor` was proposed, there was also [an alternate proposal](https://github.com/golang/go/issues/50741) which would have added a generic version of the [reflect.ValueOf](https://pkg.go.dev/reflect#ValueOf) function too. I [argued in the issue comments](https://github.com/golang/go/issues/60088#issuecomment-1544408366) that this would be a mistake: > A cursory look at just the standard library reveals dozens of places where `reflect.T[whatever]()` could be substituted in for greater clarity. `reflect.GenericValueOf` is harder to qualify because there are a few places where the interface type was clearly what was wanted, but in a lot of cases, the underlying concrete type is the target. Adding `reflect.GenericValueOf` will add a level of ambiguity when reading code: Does the author _really_ want the interface type here or did they just see generics and assume this function is newer and therefore better? It adds a second way of doing things without being 100% clear about what's intended. So I'm leaning towards +1 on `reflect.T` but +0 on `reflect.GenericValueOf`. Sometimes the best thing about the Go standard library is all the things that get left out. `reflect.GenericValueOf` would have crossed the fuzzy line into "useless use of generics" in my opinion. So that’s the story of `reflect.TypeFor`. There’s a story behind every function in the standard library. See the next entries in this series for the stories behind [slices.Concat](/post/2024/golang-slices-concat/) and [cmp.Or](/post/2024/golang-cmp-or-uses-and-history/).