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.

Reply via email to