FWIW, the "generic types" alternative syntax proposal: https://github.com/golang/go/issues/39669 includes an explicit distinction between generic interfaces and regular interfaces, and an earlier iteration of this idea included a new keyword, e.g., `prototype`, that would signal this distinction more clearly. The current proposal instead just states that a generic interface must include a type list, and if there are no constraints, it is just a "fully generic" type list: `type type`, to signal that it is a generic interface.
In any case I do think that, conceptually, for the user's benefit and mental model of what is going on, it would be useful overall to have a clear distinction between generic and non-generic types, while also preserving the shared aspects as much as possible. Interfaces *are* a form of generic-ness after all. One additional idea would be that generic interfaces can embed regular interfaces, as a way to share code while also maintaining the clear conceptual distinction: type GenericStringer interface { Stringer // include standard Stringer interface type type // makes it a generic interface } If a separate keyword such as `prototype` were used to further distinguish from regular interfaces, it would be simpler and clearer: type GenericStringer prototype { Stringer // prototypes can embed interfaces, but not the other way around } - Randy > On Aug 3, 2020, at 4:00 PM, Ben Hoyt <benh...@gmail.com> wrote: > > Per Ian's suggestion on the other thread I started > (https://groups.google.com/g/golang-nuts/c/u9jqLPhEYO0/m/tnqezci8AwAJ), > I'm breaking out this topic into a separate thread: > > It seems strange to me that interfaces with type lists are really a > different beast than regular interfaces, and aren't even meaningful as > regular interfaces. (Trying to do that gives the error "interface type > for variable cannot contain type constraints", which is relatively > clear, at least.) As soon as an "interface" has a type list, it's not > really a Go interface anymore (and interfaces with *only* type lists > are not really interfaces at all, just type constraints). This seems > confusing, though I'm not sure what the solution is. > > Ian noted that this is mentioned very briefly at > https://go.googlesource.com/proposal/+/refs/heads/master/design/go2draft-type-parameters.md#type-lists-in-interface-types > but that he can't recall much discussion on this point. > > That section in the draft design notes starkly that "They may not be > used as ordinary interface types." And then: > > "This restriction may be lifted in future language versions. An > interface type with a type list may be useful as a form of sum type, > albeit one that can have the value nil. Some alternative syntax would > likely be required to match on identical types rather than on > underlying types; perhaps type ==. For now, this is not permitted." > > That seems a little far-fetched to me, almost like a justification of > what we know to be odd / confusing in this proposal. > > In terms of a "solution" for this, one that I'm sure has been thought > about: what about keeping type constraints and interfaces completely > separate? They are half the time anyway (when there are type lists), > so why not make them separate all the time. > > I realize this may be heading back towards contracts (though without > the funky syntax for operators). I think the "Featherweight Go" paper > says "we don't need two different concepts here", but the paper > doesn't seem to discuss "type lists" at all (and type lists seem very > important to this proposal, and definitely are to this immediate > discussion). > > Anyway, instead of saying "interface" you'd say "constraint": > > // this isn't really an interface, so don't call it one: > type SignedInteger constraint { > type int, int8, int16, int32, int64 > } > > // this also can't be used as in interface, so don't call it one > type ComparableHasher constraint { > comparable > Hash() uintptr > } > > // yes, this duplicates the Stringer interface for use as a type constraint > type Stringable constraint { > String() string > } > > I realize in the design draft the "Stringer" interface is used as a > type constraint heavily, but that seems like a bit of an example/toy. > In real-world code, how likely is it that we'll be using lots of > existing interfaces as constraints? To me it seems like that won't be > common, but I don't have much to go on. > > -Ben > > -- > 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/CAL9jXCHa5%2B4LreE7acP_r3QEBMGKN6qzgzkLFv4VXsW5aoXfcw%40mail.gmail.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/202497D7-A474-48F3-B6F8-545988CB4F90%40gmail.com.