Now my head is spinning: interface{ int; m() } // int (but type set is empty because int has no method m) interface{ ~int; m() } // int (but type set is infinite because there are many int types with method m)
On Saturday, 8 January 2022 at 02:32:35 UTC gri wrote: > Indeed. There's no shortcuts possible here. Hopefully this works better > (and closely matches the implementation): > https://go-review.googlesource.com/c/go/+/376834 > - gri > > On Thu, Jan 6, 2022 at 10:08 PM Axel Wagner <axel.wa...@googlemail.com> > wrote: > >> On Fri, Jan 7, 2022 at 2:35 AM 'gri' via golang-nuts < >> golan...@googlegroups.com> 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 . >> >> >> ISTM this still fails for `int | any`, which according to the rules has >> specific types `int`, but should have no specific types. >> >> >>> >>> 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...@googlegroups.com. >>> To view this discussion on the web visit >>> https://groups.google.com/d/msgid/golang-nuts/d6e91c64-7a8a-4bd2-912b-3f9a1cb7333an%40googlegroups.com >>> >>> <https://groups.google.com/d/msgid/golang-nuts/d6e91c64-7a8a-4bd2-912b-3f9a1cb7333an%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/adc4bf9c-4048-4c74-98d9-ea730524ba94n%40googlegroups.com.