You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
structureAwherea : Unit
structureBextends A where b : Unit
structureCextends A where c : Unit
structureDextends B, C where
the type of D.mk is asymmetric:
D.mk (toB : B) (c : Unit) : D
More precisely, the representation of D is to embed an entire B structure, but then only take the parts of the C structure that do not overlap with B, namely c : Unit.
I have no doubt that this behavior is useful in some circumstances, but in situations where a symmetric API is more important than performance, this behavior is annoying.
Let's imagine that the symmetric API we want is D.mk (toA : A) (b c : Unit). Right now, there are the following workarounds to achieve that
Write the type of D manually without extends:
structureAwherea : Unit
structureBextends A where b : Unit
structureCextends A where c : Unit
structureDextends A where
b : Unit
c : Unit
-- user has to write this boilerplatedefD.toB (d : D) : B := { toA := d.toA, b := d.b }
defD.toC (d : D) : C := { toA := d.toA, c := d.c }
This boilerplate can be rather a burden, epsecially since the naive := { d with } approach performs unwanted eta-expansion
structureDFlatHackwherestructureAwherea : Unit
structureBextends DFlaHack , A where b : Unit
structureCextends DFlatHack, A where c : Unit
structureDextends DFlatHack, B, C where
which gives us D.mk (toDFlatHack : DFlatHack) (toA : A) (b c : Unit) : D, where the first argument is vacuous and can always be passed as ⟨⟩.
In Lean 3 we had set_option old_structure_cmd true; but this was a bad design because it did not allow parent structures to selectively be flattened (among other reasons).
The proposal is to remove the need for a hack here, such that the user can write
structureAwherea : Unit
structureBextends A where b : Unit
structureCextends A where c : Unit
structureDextends@[flat] B, @[flat] C where
or any other reasonable syntax.
How?
The presence of flat simply means "skip the overlapping fields check, and behave as if the fields overlap"; that is, a check for the syntactic marker would be added to the conditions here:
Nested structures break symmetries in unfortunate ways for things like RingHom, which has to pick between MonoidHom and AddMonoidHom as it's "main" parent. This affects the shape of the constructor, the simp lemmas about it, and adds ugly additional angle brackets to anonymous constructors
In both cases, having a @[flat] attribute would make it vastly easier to perform performance and API experiments in mathlib to work out where nested structures help, and where they're a hindrance.
Proposal
What?
When working with a structure hierarchy like
the type of
D.mkis asymmetric:More precisely, the representation of
Dis to embed an entireBstructure, but then only take the parts of theCstructure that do not overlap withB, namelyc : Unit.I have no doubt that this behavior is useful in some circumstances, but in situations where a symmetric API is more important than performance, this behavior is annoying.
Let's imagine that the symmetric API we want is
D.mk (toA : A) (b c : Unit). Right now, there are the following workarounds to achieve thatDmanually withoutextends::= { d with }approach performs unwanted eta-expansionD.mk (toDFlatHack : DFlatHack) (toA : A) (b c : Unit) : D, where the first argument is vacuous and can always be passed as⟨⟩.In Lean 3 we had
set_option old_structure_cmd true; but this was a bad design because it did not allow parent structures to selectively be flattened (among other reasons).The proposal is to remove the need for a hack here, such that the user can write
or any other reasonable syntax.
How?
The presence of
flatsimply means "skip the overlapping fields check, and behave as if the fields overlap"; that is, a check for the syntactic marker would be added to the conditions here:lean4/src/Lean/Elab/Structure.lean
Lines 423 to 428 in 57e2391
lean4/src/Lean/Elab/Structure.lean
Lines 479 to 483 in 57e2391
Why?
RingHom, which has to pick betweenMonoidHomandAddMonoidHomas it's "main" parent. This affects the shape of the constructor, the simp lemmas about it, and adds ugly additional angle brackets to anonymous constructorsIn both cases, having a
@[flat]attribute would make it vastly easier to perform performance and API experiments in mathlib to work out where nested structures help, and where they're a hindrance.Community Feedback
Mario originally proposed this syntax here.
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.