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 <[email protected]> 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 [email protected].
> 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 [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/golang-nuts/202497D7-A474-48F3-B6F8-545988CB4F90%40gmail.com.