-
Notifications
You must be signed in to change notification settings - Fork 810
RFC: Naming structure parent projections #7099
Description
Summary
Modify the structure syntax to be in the form
structure IDENT BINDER* [: TYPE]? [extends [[IDENT :]? TYPE]*]? where FIELDS
- The structure resultant type is moved to before the
extendsclause. - The ident prefixes in the
extendsclause are used to override the default parent projection names.
Motivation
Currently, there is no way to control the field names used for parent projections. Lean tries to automatically name parent projections using the following algorithm: if the parent has type S .., then it uses the first name among toS, toS_1, toS_2, toS_3, ... that is unused. The parent projections are not meant to be pure implementation details, so the fact that projection might use a number is less-than-ideal.
Furthermore, is possible to get into situations where this naming scheme fails. For example, suppose we have two structures with the same name in different namespace and then define
structure B extends NS1.A, NS2.AThis gives parent projections B.toA and B.toA_1. If you also have
structure C extends NS2.A
structure D extends B, Cthen there's a field conflict on the C parent:
parent field type mismatch, field 'toA' from parent 'C' has type
NS2.A : Type
but is expected to have type
NS1.A : Type
A way to fix this is to let users specify the name of the parent projection:
structure B extends toA1 : NS1.A, toA2 : NS2.AHowever, there is a syntax ambiguity with this solution. Another parse is that toA2 is a parent and NS2.A is the resultant type of B. This is clearer in the following:
structure S2 extends S1 : TypeChanging the syntax so that the resultant type comes before the extends clause would fix this.
structure S2 : Type extends S1Proposal
First, we move the resultant type to come before the extends clause. For migration purposes, we can insert an additional resultant type parser into the the end of the extends clause itself, which we can use to detect uses of the old syntax (when the parent is not an ident) and raise a warning with migration suggestions.
Second, we modify the parent field naming algorithm. For parent S .., we now use toS as the default name for the projection. If this name is already in use, we throw an error suggesting that the user use the toCustomS : S .. syntax.
In the structure elaborator, we also add checks that the projection matches the name of the projection as given by other parent classes.
User experience
Putting the resultant type before extends is its natural place. The elaboration order for structures are binders, resultant type, parents, and then fields. The parents have no bearing on the type of the type constructor, and they are more like fields.
This location of the resultant type is also less confusing, since we can read off the binders and resulting type and know what the type constructor's type is, without needing to ignore the extends clause.
This change also opens up the possibility to write structure declarations in forms such as
structure S (x : X) : Type
extends P where
a : NatHaving the ability to name parent projections is a positive change. Having projection names also makes the extends clause closer to the syntax for fields.
Beneficiaries / Maintainability
This RFC comes from core Lean development. The primary purpose is to simplify the parent projection naming algorithm, so that it does not depend on random details of how parents are represented in the structure: now it's simply toS (without a number) or the user-supplied name.
A benefit will be that it should be easier to make all parents provide instances when elaborating the fields of a structure. Currently only subobject fields are available.
Drawbacks
- This is a breaking change to the syntax.
- Some parent projections will now need explicit names now.
Unresolved questions
This RFC does not add modifiers to the extends syntax. It makes sense making parent projections be protected or private, but it is unclear whether these modifiers are meant to apply to the fields being included as well.
Community Feedback
Impact
Add 👍 to issues you consider important. If others benefit from the changes in this proposal being added, please ask them to add 👍 to it.