1. 8
  1.  

  2. 2

    Not trying to critique this package, I think this is fun and helped me understand generics a little bit more.

    But on that topic: Is this meaningfully using generics? I though any was an alias for interface{}. Does this do type checking beyond what the non-generic version would do?

    1. 4

      Is this meaningfully using generics? I though any was an alias for interface{}. Does this do type checking beyond what the non-generic version would do?

      I tried to write a non-generic version of this package first, but you can’t reflect on an interface type. When you do reflect.Value(x), you lose the fact that x was, e.g. an error, because reflect.Value only takes interface{}. You’d end up saying whether the underlying concrete type was nil or not, which is typically not what you want. To work around that, you could require that everything is passed as a pointer, e.g. reflect.Value(&err), but that kind of sucks as an API. If you look at what truthy.Value does, it accepts a value of type T, and then passes &T to reflect.Value and calls value.Elem() to get the correct type. So yes, on a technical level, you couldn’t quite make this API work without generics, although it could be close.

      Then there’s truthy.First. To be honest, truthy.First is the only part of the package that I consider actually useful, and even that, I mostly expect it to be used for picking a string or default. Anyhow, that requires generics to avoid the cast back from interface type to the concrete type. However, if you wanted to, you could write truthy.SetDefault with Go 1.17 reflection alone, since that takes a pointer. truthy.Filter is also pretty easy to do with pre-generic Go, but the code would be a lot uglier.

      1. 2

        Ah interesting. Thank you for the detailed response.

      2. 1

        afaics not, no.