-
Notifications
You must be signed in to change notification settings - Fork 17.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
proposal: spec: interfaces should not be able to contain type sets, define a new thing instead #50836
Comments
Thanks for the proposal. This would give us two kinds of things that are very similar: interfaces and constraints. That would bring us back to a path that we were on before, in which we named (what we now call) constraints as contracts. See https://go.googlesource.com/proposal/+/refs/heads/master/design/go2draft-contracts.md . When we presented that approach, many many people were concerned about the similarity between interface types and contracts--and they were actually more different than interfaces and constraints in this proposal. Because of those objections we moved away from contracts and consolidated on interface types. Also, it's too late. After years of work we've accepted a proposal that uses interface types as constraints, and, while we could tweak that, we aren't going to radically change it at this point. Therefore, we aren't going to adopt this change, and I'm going to close this issue. Sorry. |
Sum types in general is #19412. |
Disclaimer: I'm putting this out quickly without a ton of detail because I realize the odds of this being accepted are really low this late in the go 1.18 process. If there's any chance this could be accepted, I'm willing to spend a bit more time fleshing it out this weekend. I expect perhaps it's too late to consider this, and I imagine that it was discussed to death in earlier rounds of generics -- but I would argue that some of that discussion happened prior to some of the simplification of type sets, so perhaps it wasn't as compelling?
If the language releases go 1.18 as is, then we are forever stuck with interfaces that can contain type sets and this proposal would no longer make sense as post-1.18 it would introduce multiple ways to do the same thing, which is not very go-like.
Disclaimer 2: I've only been really trying to use generics for 2 days, but I hope my fresh perspective is useful in this case
Proposal
Constraints that contain type sets may only be a "constraint" type instead of an "interface". For example:
This would no longer be allowed:
Rationale
When I first started playing with generics, it took me some time before I needed to play with type sets. I created my own for something and since "it was an interface" I started trying to use it like an interface in the same places that you would normally use an interface (for example, #50813). But you can't do that, and it wasn't really clear to me immediately why that was.
From the type parameters proposal: "Go already has a construct that is close to what we need for a constraint: an interface type". But it's close. It's not the same, and shouldn't be the same.
I've definitely struggled at first to understand where I can use these new magic interfaces and where I can't use them. I believe that if they were separate things then it would be easier to bridge that gap.
Interfaces with type sets are not like other interfaces and cannot be used in most other places that an interface can be used
Interfaces with type sets introduce ambiguity
It's also really easy to not notice that a particular interface is a constraint:
What is that? Is that an interface that has an embedded interface, or is it an interface that can only be used as a constraint? Without knowing what CoolThing is, it's ambiguous to a human reading the code.
I don't know of many other places in golang where things are quite this ambiguous, but that could be a lack of experience.
Magic remote breakage
Here's another dumb idea I thought of -- which honestly this is a stretch, but possible in undisciplined projects. Let's say a library defines an interface that they only use as a generic constraint
A user of the library finds it useful, extends it:
Or even worse, returns it because after all "its just an interface":
The next release of the library, the since the author was only using the interface as a generic constraint, decides to add a type set to the interface. Now any user that was trying to use that interface like a normal interface is broken.
Granted, this could still happen too if for example the library author changed the type of a particular name from an interface to a struct -- but it's a bit more egregious and more obviously a Bad Thing. If you're already only using an interface in a generic constraint context, "just" adding a type set is definitely a lot more non-obvious that you're going to break consumers of your library.
Why shouldn't you accept this proposal
constraint
type also implies that interfaces cannot be used as a constraint for a generic function/etc, which wouldn't be true.Other
comparable
#50791 -- comparable becomes a constraint type, instead of a magic interfaceconstraint cannot be used as a variable
constraint cannot be used as a function parameter
Finally
Thanks for your consideration.
The text was updated successfully, but these errors were encountered: