On Wednesday, June 17, 2020 at 12:08:59 AM UTC-4 Ian Lance Taylor wrote: > On Tue, Jun 16, 2020 at 9:04 PM Xie Zhenye <xiez...@gmail.com> wrote: > > > > I agree. constraint is different from normal interface. It's better to > use type SomeConstraint constraint {} than type SomeConstraint interface {} > > That is an option, but then we would have two different concepts, > constraints and interfaces, that are very very similar. It's not > clear that that is better. >
I think we already have two very different concepts — we're just conflating them together by giving them the same name. As far as I can tell, the semantics of non-type-list interface types and the semantics of type-list interface types are not compatible. Today, if we have two interface types T1 and T2, with T1's method set is a superset of T2's, then any value assignable to T1 is also assignable to T2: that is, T1 is a subtype of (not just assignable to!) T2. That observation is also reflected in the Featherweight Go paper, in which a type argument satisfies a type constraint if (and only if) the argument is a subtype of the constraint. Based on the semantics of type-lists in type constraints, I would expect that a run-time interface type containing a type list would mean “an interface value whose dynamic type is one of the listed types”, or perhaps “an interface value whose dynamic type has one of the listed types as its underlying type”. For consistency, such interfaces should also have the same sort of subtyping relationship: if type T1's type-list is a strict subset of T2's type-list, then any value assignable to T1 (including a variable of type T1 itself!) should be assignable to T2. So, for example: type SmallInt interface { type int8, int16 } should be a subtype of type MediumInt interface { type int8, int16, int32 } However, in the current design draft, a constraint that is a type-list interface allows use of the operators common to the types in the list. In the presence of type-list subtypes of interface types, the semantics for those operators would be confusing at best. Consider the program: func Add(type T MediumInt)(x, y T) T { return x + y } func main() { var a int8 = 127 var b int16 = 1 fmt.Println(Add(SmallInt)(a, b)) // Should this print 128, or -128? } So type-lists as they are defined in the current draft either cannot have the subtyping properties of ordinary interfaces, or must have a meaning as type constraints that is fundamentally different from their meaning as interfaces. Either way, they don't seem at all consistent with ordinary interfaces to me, so I would prefer that we not call them interfaces. ---- On the other hand, if we accept that there is a fundamental difference between concrete-type constraints and type-list interfaces, then perhaps the type-list interfaces and the “concrete underlying type” constraints could be made orthogonal. Consider, instead of an interface, a constraint indicating that the type parameter must be a *concrete* type implementing the given interface: func Add(type T concrete(MediumInt))(x, y T) T Now the problem is once again resolved: even if SmallInt is a valid run-time interface, it is not a concrete type and cannot satisfy a concrete-type constraint. > On Wednesday, June 17, 2020 at 11:12:24 AM UTC+8 Brandon Dyck wrote: > >> > >> I find it a little strange that an interface with a type list can only > be used as a constraint, and not as the type of a variable or parameter, > despite it using basically the same syntax as a normal interface. Is this > difference between constraints and other interfaces a property of the type > system, or just a limitation of the translation? I don't think it was > explicit in the design document. It would certainly be useful to declare > variables with type-list interfaces, as it would provide a much less hacky > way to define sum types than using an unexported interface method as in > https://medium.com/@haya14busa/sum-union-variant-type-in-go-and-static-check-tool-of-switch-case-handling-3bfc61618b1e. > > > >> > >> My failing example is at https://go2goplay.golang.org/p/-lQ0jKs8_hU. > > > > -- > > 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...@googlegroups.com. > > To view this discussion on the web visit > https://groups.google.com/d/msgid/golang-nuts/88aa126b-d8f1-49c0-84cd-c0ea8cd87d39n%40googlegroups.com. > > > -- 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/f0e7753a-af88-4481-9df1-8d884558803cn%40googlegroups.com.