On Wed, Oct 4, 2023 at 6:54 AM Jon Watte <jwa...@gmail.com> wrote: > > where it is important to permit only type arguments that can be compared > to nil > > I see! As in, if we somehow got a "equalszero" constraint, then that > constraint would solve the problem I illustrate. > I believe that assertion is correct, but I also believe that is a stronger > assertion, and also that it introduces more of a new concept than a simple > "nil" constraint. (Unless you're looking for some way to make "any" work, > and introduce a zero keyword or something...) >
Yes, that is what #61372 <https://go.dev/issue/61372> proposes: Introduce a `zero` predeclared identifier (!) that is assignable to any type and comparable to any type. With some discussion about whether it should only apply inside generic code or not. There is no proposal (as far as I know) for anything like an "equalszero" constraint, as every type can be assigned a meaningful comparison to its zero value, so it seems we should just allow it for all types. To be clear, the criticism of a `nilable` constraint is 1. It only solves a subset of the problem we are seeing. You gave examples from that subset. I gave some examples of problems we are seeing that are *not* in that subset. 2. It is not really clear this particular subset is particularly important. Why is the *specific* split into (interfaces, pointers, slices, functions, maps, channels) and (numbers, booleans, strings, structs, arrays) a particularly important one? 3. As long as that is not clear, it seems more prudent to focus on mechanisms that solve more of the problems we are seeing. FWIW I could, personally, get more (though still not fully) on board with an `isinterface` constraint, that would allow *only* interfaces. It would still allow assignment and comparison to `nil`. But it seems far clearer to me, that interfaces can be singled out. While a `nil` interface is categorically an invalid value, the same is not true for `nil` pointers/maps/channels/funcs *in general*. Any of those kinds of types could still have methods callable on them that work perfectly fine (by doing an `if receiver == nil` check in the method). You categorically can't call a method on a `nil` interface. And an `isinterface` constraint could still conceivable be useful for many of the examples you mentioned. Or it would allow func Convert[J isinterface, T I](s []T) []J { out := make([]I, len(T)) for i, v := range s { out[i] = J(v) } return out } I'd still not be convinced this is really worth it, but at least it seems clearer why that particular subset of types deserves to be singled out. In fact, many people have argued that the interface zero value really shouldn't have been spelled `nil`, because interfaces have so little in common, conceptually, to other "nilable" types. > > Also, there's the ergonomics of having to make a zero value instance. > Maybe we can rely on the compiler to optimize it away, but at a minimum it > adds another required line of code in the implementation. E g: > > func MaybeNuke[T nil](b bool, val T) T { > if b { > return nil > } > return val > } > > func MaybeNuke(T zero](b bool, val T) T { > if b { > var nope T // an extra line! > return nope > } > return val > } > > func MaybeNuke(T any](b bool, val T) T { > if b { > return zero[T]{} // maybe? seems weird > } > return val > } > > This is because not all zero values can be instantiated inline with simply > T{}. > > Sincerely, > > Jon Watte > > > -- > "I find that the harder I work, the more luck I seem to have." -- Thomas > Jefferson > -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/CAEkBMfHAW%3DjDmkvDs8VS373c%3DYFVTn2%3D2d0mLXdbAUnMM3wT%2BA%40mail.gmail.com.