On Wed, Jan 20, 2021 at 11:08 AM Brian Candler <b.cand...@pobox.com> wrote:
> The end result is there's a crucial but subtle difference between: > > type Foo interface { ... } > func f(v Foo) ... > > and > > type Foo interface { ... } > func f[T Foo](v T) ... > > Given that the second case supports both concrete types *and* interface > types, then it seems to me that comparing a value with nil is a > semantically valid thing to do. > FWIW, it's also possible to write a constraint that can *only* be satisfied by concrete types - namely one containing a type-list. IMO it is confusing to allow comparing generic values to nil, in general. If we could, I would either assume I can compare any *non*-generic value to nil. I would assume we can always go from a generic function to an instantiated one by substituting all occurrences of the type-parameters. But IMO, nil is already confusing enough as it is. I think the solutions Patrick and Ian provided for checking if an interface is nil, or a value is zero, are enough. Because, to be clear: Calling a method on an interface can panic *whether or not that interface is nil*. Fundamentally, the case where a caller passes you a nil-interface is not different from the case where a caller passes you an interface with a method that dereferences a nil-pointer or accesses a slice out of bounds - or an interface that just calls panic("foo") in one of its methods. It's a bug in the caller and panicing in such a case is the correct thing to do. You will never be able to statically catch all bugs or statically prevent all panics. I don't think this particular panic is special enough to give it extra attention - because, again, you *can* do the check, if you want to, it's just not super convenient. If the function specialisation is a concrete type, then that comparison > would always be false and the code path optimised out. > > Alternatively, generics could exclude interface values. But then you get > the weird situation that a generic function declaration that *looks* like > an interface type, explicitly disallows interface type values! > > ---- 8< ---- > > With my wild hat on: it makes me wonder what would happen if the generics > proposal became nothing more than interfaces with linked constraints - so > that you could say "this function takes a function of type T (interface C) > and returns *the same type* T", or "this function takes a []T and returns a > value of *the same type* T". > > What I mean is, the difference between > func f(a, b fmt.Stringer) c fmt.Stringer { ... } > and > func f[T fmt.Stringer](a, b T) c T { ... } > would simply be that a, b and c had to be of the *same* concrete type - > but were otherwise still interface values (and specialisation, if > implemented, would just be a hidden optimisation). > > The obvious problem is that if you actually pass interface values around, > then many type-mismatch violations couldn't be detected until runtime. > > However: I find the same problem occurs with the current generics > implementation, *if* you pass interface variables. Check this out: > https://go2goplay.golang.org/p/F08gh5gotsO > Print2() expects that both arguments are of the same type - but in the > final call, they are not! There is neither compile-time nor run-time error. > > ISTM that constrained interface types *could* also be checked at compile > time, in the common case where the caller passes concrete types. Rewriting > to use plain interfaces instead of generics: > https://go2goplay.golang.org/p/CfkvAcgr8mC > I think that an interface type constraint system *could* statically check > that both args of the first Print2() call were (or were not) the same type. > > What you might end up with is linked type constraints being a natural > extension of interfaces. Generic specialisation would just be an > optimisation on top of that (if the call site knows that a particular set > of concrete types is being used). Type lists could also become an > extension of interfaces. > > However, that's just off the top of my head. Whilst I've been following > generics intermittently, no doubt this has been considered (and discarded) > before. > > Regards, Brian. > > -- > 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/34bdb40e-ad0b-47ce-8588-d014d0886470n%40googlegroups.com > <https://groups.google.com/d/msgid/golang-nuts/34bdb40e-ad0b-47ce-8588-d014d0886470n%40googlegroups.com?utm_medium=email&utm_source=footer> > . > -- 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/CAEkBMfGv4iTzqNYnG%2BeQafi5ShgrOEpCtSToR_LTneuAHhMagQ%40mail.gmail.com.