On Tue, Aug 18, 2020 at 1:48 PM Frederik Zipp <frederik.z...@gmail.com> wrote: > > Ian Lance Taylor schrieb am Dienstag, 18. August 2020 um 21:26:23 UTC+2: >> >> What would it mean to permit any type as a constraint? > > > Each type would match exactly the same types it would match in a plain old > function parameter list:
Well, that's assignability. >> I actually looked into this, to see if we could say that any type >> could be used as a constraint, and say that a type parameter >> constraint would permit any type argument that is assignable to the >> constraint type. Unfortunately that leads to some odd behavior. If >> we use a named type as the constraint, it may have methods. But we >> can use a corresponding type literal as a type argument. That would >> add methods to a type literal with no explicit type conversion. > > > But isn't that already the case with normal function parameters? > > package main > > type S struct{} > > func (s S) M() {} > > func F(s S) { > s.M() > } > > func main() { > // no explicit type conversion from struct{} to S > F(struct{}{}) > } Yes, but here you are assigning the value struct{}{} to the type S. That's not how type arguments work: type arguments are not assigned to type parameters. Instead, the body of a generic function or type is instantiated with the type argument. In a generic function, rather than assigning a value struct{}{} to type S, we are replacing instances of S in F with struct{}. But struct{} has no methods. So can you call method M on an argument whose type is the type parameter? Why or why not? >> Similarly, if we use a type literal as a type, we can use a defined >> type as a type argument. But the generic function could assign the >> type parameter to some other defined type, and now we have a generic >> function that could not be compiled if we simply substituted the type >> argument for any instance of the type parameter. > > > Same here: > > package main > > type S struct{} > > func (s S) M() {} > > func F(s struct{}) { > var x S = s > _ = x > } > > func main() { > // no explicit type conversion from S to struct{} > F(S{}) > } Same answer. Instantiation is not assignment, so is assignability the right rule for constraint satisfaction? >> And I don't see what we gain by following that path. > > > It would mostly be for the sake of consistency, and as a justification for a > hypothetical sum type like `anyof` (as a replacement for type lists in > interfaces) to be usable as a constraint. Fair enough. Ian -- 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/CAOyqgcUVOm6UJgbKwC-dc_jnoAn3ku-MjvrRSyXnOH7kPVCx2w%40mail.gmail.com.