Coming back at this after more thought & exploration. The fundamental 
problem I see is it introduces complexity, but no value.

Say 
`type I interface {...}`
`type S(type T I) struct {T}`
Then the generic S (before instantiating with a particular T) may implement 
any interface, e.g. in any method on S or any other generic code using S, 
you may have
`_, ok := (interface{}(S(...){})` ).(Whatever)`
and the result of ok depends on what T is used. Without embedding, that is 
strue of T but not S.

# What value did this add?
- You can call methods listed in I directly, e.g. if method Foo is in 
listed I, you can do s.Foo().
    => without embedding using s.I.Foo() is hardly a change.
- You can implement interfaces based on method listed in I directly, e.g. 
if method Foo is listed in I and characterises interface Fooer, you can do 
Fooer(s).
    => without embedding, you can do Fooer(s.I) or if you actually want s 
in the interface, write a generic method Foo in S and keep Fooer(s).
- You can implement interfaces based on method NOT listed in I directly, 
e.g. if method Foo is NOT listed in I, but is defined in some T and 
characterises interface Fooer, you can do Fooer(s) (for s := S(T){...}).
    => without embedding, you can't do this. You can do Fooer(s.I), or 
create a new type for this specificT,  `type X S(T)`, and implement method 
Foo, but let's assume that neither is acceptable. How realistic / in what 
circumstances do you want this? If you require a struct to have a method 
not listed in any contract but present in the type that happens to be 
embedded on this instance of the generic, and want it to be assigned to an 
interface that uses that method but won't accept either the embedded field 
in the interface, nor a separate type derived from it with the additional 
method, I'd say you need to re-evaluate your requirements because you are 
not following any moderatly sensible standards, or at the very least accept 
you are doing something wild and can't use generics for it.

# What did this cost?
- Complexity => the possibility of there being more methods available in a 
struct than listed in its definition is in itself one more thing to think 
about.
- Refactoring => an embedding can't be refactored without a breacking 
change (can't change `type S(type T I) struct {T}` to `type S(type T I) 
struct {T}` + methods in I), since users may be relying on methods not 
present in I. 
- Limits to Tooling: without embedding, `_, ok := (interface{}(S(...){})` 
).(Whatever)` above may always be false and the tooling may be able to 
identify and flag that, with embedding there is nothing it can do since it 
may always be true.

# No arbitrary restrictions
"our hope is to make generic types work as much like ordinary types as 
possible, without arbitrary restrictions"
    => this is indeed a restriction, and I don't know how much that weights 
in the go team's mind regarding future features, etc. But on the other hand 
even allowing embedding in generics isn't quite as pre-generics go either, 
after all you are embedding using the generic's type name (in my example, 
T) and not the name of the actuall type T is instantiated with. In other 
words, the type produced can't be replicated without generics. Banning 
embedding you limit slightly the types you can produce, but at least those 
that are allowed are valid pre-generic go types.

And of course there is also a 'delay decision' argument here: if embedding 
is banned, it can be added later. If it is allowed, the decision is final. 

I do not claim anything dramatic about this feature's significance, like 
generics with fail if embedding is allowed, but also generics will not fail 
because they weren't. So if there is no strong reason for, and there are 
some reasons against, it seems to me the best decision is to ban at first 
and re-evaluate later.
On Tuesday, July 14, 2020 at 11:41:42 AM UTC+2 Javier Zunzunegui wrote:

> Issue openned in https://github.com/golang/go/issues/40199.
>
> Still clarifying my thoughts on embedding types within generics, will 
> postpone this debate while I focus on other parts of the proposal and gain 
> some more experience using the go2 branch. Not calling for any action here 
> at this point. Thanks Ian. 
> On Monday, July 13, 2020 at 7:03:35 PM UTC+2 Ian Lance Taylor wrote:
>
>> On Mon, Jul 13, 2020 at 9:15 AM 'Javier Zunzunegui' via golang-nuts
>> <golan...@googlegroups.com> wrote:
>> >
>> > In the context of Type Parameters - Draft Design#generic-types:
>> >
>> > Type embedding is allowed in the proposed generic changes. Oddly, the 
>> current implementation allows for calling methods in the embedded types but 
>> not using the method to satisfy an interface (here). That seems like a bug 
>> in the implementation.
>> >
>> > More significantly, it allows for calling not just the methods declared 
>> in the interface, but also methods available to the instantiated type but 
>> not part of the interface. Example here. I can't see what is the gain in 
>> allowing that, and it presents a risk as the interfaces satisfied by types 
>> originating from the same generic type will differ not only in the types of 
>> the methods, but also i the method names themselves.
>> >
>> > Would it not be best to not allow embeding in generic types?
>>
>> At least at first glance these just seem like bugs in the current
>> implementation, not in the design draft as such. Would you mind
>> opening an issue for these problems? Thanks.
>>
>> We could ban embedding type parameters, but our hope is to make
>> generic types work as much like ordinary types as possible, without
>> arbitrary restrictions. The existence of bugs doesn't in itself seem
>> like a good enough reason to ban the feature.
>>
>> 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/36bae6eb-4537-4796-8c11-60e828a36d51n%40googlegroups.com.

Reply via email to