Thanks for the reply, gri. The latest generics design and implementation are much more beautiful than I expected, though I still think there are many restrictions.
BTW, it looks the following line in spec becomes depreciated now, as now any type could be embedded in interfaces. In a slightly more general form an interface T may use a (possibly qualified) interface type name E as an interface element. This is called *embedding* interface E in T. On Friday, January 7, 2022 at 9:34:41 AM UTC+8 gri wrote: > Thanks for raising this issue. This is clearly a bug in the spec, or at > the very least "an imprecision". Hopefully this is better: > https://go-review.googlesource.com/c/go/+/375799 . > > The set of specific types is an approximation for the actual type set. In > practice we only need to consider those explicitly mentioned types. If the > type set is infinite, we can't do much (with respect to operations). To > make that simple elsewhere in the spec we want the set of specific types be > empty in that case. An alternative approach might be to say the set of > specific types is infinite in that case and exclude such infinite sets > where we look at specific types. > > - gri > > On Thursday, January 6, 2022 at 1:23:31 PM UTC-8 axel.wa...@googlemail.com > wrote: > >> The more I think about it, the more I'm inclined to agree that there is >> something wrong with the spec (and maybe the idea of sets of specific types >> in general). >> Because what's the set of specific types of `interface { int | any }`? >> From the definition, it should be `int` - the union with an empty set is a >> no-op. But the *type set* of that is all types. Which means that this >> should be allowed, as per the spec, which is obviously nonsense: >> >> type C interface { >> int | any >> } >> >> func F[T C](v T) { >> fmt.Println(int(v)) >> } >> >> So, logically, the type set of an interface type without type elements >> should really be the set of all types (or rather "the set of all underlying >> types"), not the empty set, for the algorithm to make sense. In that case, >> the specific types of `int | any` are the set of all types and the specific >> types of `int ; any` is `int`. >> >> I'm not sure if this would be sound, though, as we now get back to the >> situation of reducing back from the set of all types to some subset. Maybe >> the new restrictions put in place (namely that interfaces with methods >> can't appear in unions) are enough to make this easy to manage. I don't >> know. Thinking through that would take time. >> >> On Thu, Jan 6, 2022 at 8:37 PM Ian Lance Taylor <ia...@golang.org> wrote: >> >>> On Thu, Jan 6, 2022 at 11:32 AM Axel Wagner >>> <axel.wa...@googlemail.com> wrote: >>> > >>> > On Thu, Jan 6, 2022 at 8:18 PM Ian Lance Taylor <ia...@golang.org> >>> wrote: >>> >> >>> >> On Thu, Jan 6, 2022 at 8:59 AM 'Axel Wagner' via golang-nuts >>> >> <golan...@googlegroups.com> wrote: >>> >> > >>> >> > • From the definition of type elements, we can see that an embedded >>> interface type is a type element. Therefore, `any` is a type element. >>> >> > • `any` is an alias for `interface{}`, therefore it is a type >>> without any type elements, therefore the set of its specific types is empty >>> ("For an interface with no type elements, 𝑆 is the empty set."). >>> >> > • `interface{ int; any }` is a type with two type elements. "For an >>> interface with type elements, 𝑆 is the intersection of the specific types >>> of its type elements.". Intersecting with an empty set (the specific types >>> of `any`) gives an empty set >>> >> > • Therefore, the set of specific types of `interface{ int; any }` >>> is the empty set. >>> >> >>> >> That doesn't seem right. "any" is an interface type and writing >>> >> "interface { any }" just embeds the empty interface, which has no >>> >> effect. >>> > >>> > >>> > I think it has no effect on the type set. But it has an effect on the >>> set of specific types. >>> > >>> > I believe both the rule "for an interface type without type elements S >>> is empty" and the rule "for an interface type with type elements, S is the >>> intersection of the specific types of its type elements" are vital to the >>> working of S - they are, what makes the set easily computable. >>> > >>> > To answer the question from your comment in the CL: I believe the >>> grammar is very unambiguous about `any` being a type element: >>> > >>> >> InterfaceType = "interface" "{" { InterfaceElem ";" } "}" . >>> >> InterfaceElem = MethodElem | TypeElem . >>> >> MethodElem = MethodName Signature . >>> >> MethodName = identifier . >>> >> TypeElem = TypeTerm { "|" TypeTerm } . >>> >> TypeTerm = Type | UnderlyingType . >>> >> UnderlyingType = "~" Type . >>> > >>> > >>> > There is no signature, so it's not a MethodElem. Therefore it must be >>> a TypeElem. >>> >>> Yeah, I think there is something wrong in the current spec. It can't >>> be the case that embedding an interface eliminates all specific types. >>> >>> 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/9e874bdc-5a88-45be-b4e7-cd3798347837n%40googlegroups.com.