-
Notifications
You must be signed in to change notification settings - Fork 1.5k
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
Associated type syntax #739
Comments
Open discussion is leaning toward option 1. The specified type in the impl should be equal to the associated type in the interface, or more restrictive. Or the type can be explicitly set to |
@josh11b prompted me to write down at least my memory of the rationale from the discussion we had... Why not option 3? This one I think was only very briefly discussed and not preferred because:
Why not option 2? This was a more complex discussion. The big advantage and disadvantage of option 1 compared to option 2 is that it allows you to specify the constraints for a specific implementation. These must at least include those in the interface, but could include further constraints. That results in a tradeoff when evolving constraints on interfaces. Let's look at the implications of different evolutionary changes to the constraint on the interface's associated type. There are two kinds of changes here: adding or removing a constraint. Option 2 seems to help when adding a constraint that all implementations of the interface already satisfy. If any don't already satisfy the constraint, this would be a breaking change until those implementations are updated to satisfy it. Option 1 is a tradeoff here: it requires updating the implementations even when they already satisfy the added constraint just to say that they do. But it also makes it easier incrementally enforce greater constraints. So in the scenario of adding a constraint, this seems like it would make it easier to incrementally roll out and enforce the change at the cost of higher churn when most things Just Work. When removing a constraint, there is little difference if the implementations aren't using that constraint in some other way -- for example due to aliasing reusing the associated type in other contexts which need that constraint, or user code that directly uses it (even though it was unnecessary). So when removing a constraint isn't a fundamentally breaking change, the options seem similar. If removing the constraint from the implementation would be a breaking change, option 1 seems to make it easier to preserve the functionality. On the whole, it seems like both could be made to work. You can alias a normal But on balance, it seemed better to try putting the explicit constraints into the implementations so that we have more tools to incrementally roll out changes to interface constraints even though those rollouts will as a consequence be more noisy in some cases. If experience shows that this is a really bad tradeoff, we should revisit it. |
This decision was revised by #1013; we now use:
|
This is an open question in #731 , specifically see https://github.com/josh11b/carbon-lang/blob/details/docs/design/generics/details.md#associated-types
Problem
Given an interface with an associated type:
how should an impl specify the value for that associated type?
Option 1:
let :! =
This matches the syntax of other
let
declarations in the class.Option 2:
let =
This is more concise, and doesn't repeat what is already in the interface. This allows the constraints on the associated type expressed in the interface to change without having to change all implementations of that interface.
Option 3:
let
is optionalSee https://github.com/josh11b/carbon-lang/blob/details/docs/design/generics/details.md#inferring-associated-types
In this case, the value of
ElementType
is deduced from the signature ofPush
, which usesT
in theElementType
position. This is the approach used by Swift.Advantages:
Disadvantages:
The text was updated successfully, but these errors were encountered: