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.

Reply via email to