<div dir="ltr">Arnaud,<div><br></div><div>That is a good argument. Without an opt-in to the new syntax, they can't adapt. I guess this brings us to the extension lifecycle. A solution could be</div><div>1. Deprecate OverloadedRecordUpdate in favour of OverloadedRecordUpdateNew. The user can adapt their code and use a different Extension.<br></div><div>2. Eventually Have OverloadedRecordUpdateNew be a synonym for changed OverloadedRecordUpdate. And Deprecate OverloadedRecordUpdateNew</div><div>    over a longer period of time.</div><div><br></div><div>I think this actually shows the value a `--std=experimental` could have. If `OverloadedRecordUpdate` was behind `--std=experimental` breaking it would</div><div>be permissible by design. And we would not have this discussion, and Adam would not need to try to find all the potential breaking codes. This is part</div><div>of the proposal to make `--std=experimental` a thing, allow fast(er) paced iteration on the experimental side of the compiler, while being extremely</div><div>explicit about it being experimental features that can break at any time and without warning.</div><div><br></div><div>The deprecation process outlined above would be fore non-experimental features. They can still be changed, but with a more rigorous change evolution.</div><div><br></div><div>I hope this helps to clarify my position?</div><div><br></div><div>Best,</div><div> Moritz</div><div><br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Tue, 3 Oct 2023 at 15:31, Arnaud Spiwack <<a href="mailto:arnaud.spiwack@tweag.io">arnaud.spiwack@tweag.io</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div>@Moritz: very clear thank you, though I'd like to understand how one could adapt during the transition period to an argument swap, would you say? Secondary question: if they can't adapt, isn't there a risk of making the breakage more painful by delaying it, and letting more people use -XOverloadedRecordUpdate with the argument order which isn't the final one?<br></div><div><br></div><div>@Adam: we have to recognise that Hackage is not all the Haskell code. I expect Hackage to be a little more conservative in extensions than end-user applications. As such we're not guaranteed an absence of breakage (it's still probably quite small, but it's hard to quantify).<br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Tue, 3 Oct 2023 at 09:21, Adam Gundry <<a href="mailto:adam@well-typed.com" target="_blank">adam@well-typed.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex">The backwards compatibility impact here is really extremely small, <br>
because OverloadedRecordUpdate is essentially unusable at present (as <br>
well as being explicitly documented as subject to change), so nobody <br>
uses it. While someone could implement a warning when the extension is <br>
turned on to say that it will change in the future, I'm not sure I see <br>
much point.<br>
<br>
I used <a href="https://hackage-search.serokell.io/?q=OverloadedRecordUpdate" rel="noreferrer" target="_blank">https://hackage-search.serokell.io/?q=OverloadedRecordUpdate</a> to <br>
look for occurrences of OverloadedRecordUpdate on Hackage, and I found <br>
precisely one pair of packages using it "for real":<br>
<br>
large-anon-0.3.0<br>
large-records-0.4<br>
<br>
These packages were created by my colleague Edsko in discussion with me, <br>
and will need to be amended when the proposal is implemented, because <br>
they want to take advantage of the new functionality.<br>
<br>
The other packages on Hackage containing the string <br>
OverloadedRecordUpdate are tools that reference all extensions:<br>
<br>
Cabal-syntax-3.10.1.0<br>
extensions-0.1.0.0<br>
fourmolu-0.14.0.0<br>
ghc-9.6.3<br>
ghc-boot-th-9.6.3<br>
ghc-exactprint-1.7.0.1<br>
ghc-hs-meta-0.1.2.0<br>
ghc-lib-9.6.2.20230523<br>
ghc-lib-parser-9.6.2.20230523<br>
hackport-0.8.4.0<br>
haskell-src-meta-0.8.12<br>
hindent-6.1.0<br>
hlint-3.6.1<br>
ormolu-0.7.2.0<br>
<br>
plus there are a few references in comments:<br>
<br>
lifx-lan-0.8.2<br>
optics-core-0.4.1.1<br>
pvector-0.1.1<br>
record-dot-preprocessor-0.2.16<br>
tztime-0.1.1.0<br>
<br>
While I generally agree with the "don't abruptly break existing code" <br>
position, in this case I don't think there is code out there to break.<br>
<br>
Adam<br>
<br>
<br>
On 03/10/2023 01:14, Moritz Angermann wrote:<br>
> Arnaud,<br>
> <br>
> thank you for your write up. And sorry that my view seems to be not <br>
> clear. Let me try to explain.<br>
> My position is: I'm against anything that _abruptly_ breaks existing <br>
> code. That's basically all there is to it.<br>
> Therefore I'm strongly against breaking changes without an appropriate <br>
> warning period (from the compiler).<br>
> I also strongly believe that most people do not read documentation, and <br>
> the authoritative messages are<br>
> the ones the compiler produces. As I've alluded to in a different email, <br>
> there are lots of people who work<br>
> on software as a 9-5 job, and don't spend their freetime tinkering and <br>
> playing with languages. They just<br>
> want to get the job done they are assigned. I have a lot of respect for <br>
> them. In my experience they don't<br>
> read compiler release announcements, or even go and read the compiler <br>
> documentation. They are given<br>
> the compiler version the company decided on for use in production. <br>
> That's the tool they use. And that tool<br>
> in my opinion needs to be rock solid, and not break easily across <br>
> versions. Thus yes, I would very much<br>
> like to see us not have breaking changes at all, but I can see that we <br>
> may need breaking changes<br>
> occasionally. In those cases I want it to be very visible to the <br>
> consumers that this breaking change is<br>
> coming towards them (compiler warnings). Giving them some time to adjust <br>
> (migration period), until the<br>
> breaking change happens.  Ultimately we should be able to compiler <br>
> existing code that compiles today<br>
> with at least the next compiler without it rejecting the code or needing <br>
> modifications to the code (-Werror<br>
> excluded).<br>
> <br>
> Thus what I'm arguing for is:<br>
> - Let's implement this backwards compatibility.<br>
> - Add compiler warnings about the arguments being swapped in a future <br>
> GHC version. For _a least_ one major release.<br>
> - Make the breaking change in a subsequent release.<br>
> <br>
> Alternatively I could also see:<br>
> - Adding compiler warnings now that the arguments will be swapped in a <br>
> future GHC version (for at least one major release).<br>
> - Implement the breaking change in a subsequent release.<br>
> <br>
> Either of those would be ok with me. Implementing a breaking change from <br>
> one version to the next, without an<br>
> appropriate deprecation/migration period (that is, the compiler will <br>
> warn loudly that changes are coming) is something<br>
> I am _very_ vehemently against.<br>
> <br>
> If the migration/deprecation warnings would provide a link to a GitHub <br>
> ticket or something where more information<br>
> can be found and maybe even a discussion could be had would probably <br>
> also be a good idea.<br>
> <br>
> I hope this helps clarify my position? If not, feel free to ask more, <br>
> I'm also happy to jump onto a call to explain my<br>
> position if needed.<br>
> <br>
> Best,<br>
>   Moritz<br>
> <br>
> <br>
> On Mon, 2 Oct 2023 at 23:31, Arnaud Spiwack <<a href="mailto:arnaud.spiwack@tweag.io" target="_blank">arnaud.spiwack@tweag.io</a> <br>
> <mailto:<a href="mailto:arnaud.spiwack@tweag.io" target="_blank">arnaud.spiwack@tweag.io</a>>> wrote:<br>
> <br>
>     Sorry I took a little bit of time to react to this, it was a lot to<br>
>     take in and I didn't have the mental space last week.<br>
> <br>
>     The only person that may have spoken against the current state of<br>
>     the proposal is Moritz. Yet I realise that I don't actually know,<br>
>     Moritz, what your position is.<br>
> <br>
>     To recap: to use -XOverloadedRecordUpdate in current GHC, you need<br>
>     to use -XRebindableSyntax and provide a setField function. In the<br>
>     new proposal you can use -XOverloadedRecordUpdate without<br>
>     -XRebindableSyntax, but when -XRebindableSyntax is on, the setField<br>
>     function that you have to provide has its argument swapped. The<br>
>     current documentation of OverloadedRecordUpdate has the following<br>
>     text at the top “*EXPERIMENTAL* /This design of this extension may<br>
>     well change in the future. It would be inadvisable to start using<br>
>     this extension for long-lived libraries just yet./”.<br>
> <br>
>     Now, I don't quite see how we could have a transition period that<br>
>     would allow a smooth transition there. There is no piece of code,<br>
>     with RebindableSyntax, that would compile before and after the<br>
>     change. So unless I'm missing something the position we can take as<br>
>     a committee can be either<br>
>     - Let's have the breakage without a transition period<br>
>     - Let's not make the breaking change ever and use the earlier<br>
>     argument order for set<br>
> <br>
>     Which one do you argue for, or am I missing another option?<br>
> <br>
>     On Sun, 24 Sept 2023 at 15:36, Eric Seidel <<a href="mailto:eric@seidel.io" target="_blank">eric@seidel.io</a><br>
>     <mailto:<a href="mailto:eric@seidel.io" target="_blank">eric@seidel.io</a>>> wrote:<br>
> <br>
>         I am in favor of this proposal.<br>
> <br>
>         On Thu, Sep 21, 2023, at 03:37, Arnaud Spiwack wrote:<br>
>          > Dear all.<br>
>          ><br>
>          > I submitted my recommendation 3 weeks ago, and only Simon has<br>
>         commented<br>
>          > yet. Please let me know your thoughts.<br>
>          ><br>
>          > On Wed, 6 Sept 2023 at 16:27, Arnaud Spiwack<br>
>         <<a href="mailto:arnaud.spiwack@tweag.io" target="_blank">arnaud.spiwack@tweag.io</a> <mailto:<a href="mailto:arnaud.spiwack@tweag.io" target="_blank">arnaud.spiwack@tweag.io</a>>> wrote:<br>
>          >> Dear all,<br>
>          >><br>
>          >> Don't forget to opine here. To reiterate, I really don't<br>
>         expect the proposal to be controversial. The text of the<br>
>         proposal is rather long, but is made easy to read. So it<br>
>         shouldn't take too much of your time.<br>
>          >><br>
>          >> /Arnaud<br>
>          >><br>
>          >> On Thu, 31 Aug 2023 at 01:03, Simon Peyton Jones<br>
>         <<a href="mailto:simon.peytonjones@gmail.com" target="_blank">simon.peytonjones@gmail.com</a><br>
>         <mailto:<a href="mailto:simon.peytonjones@gmail.com" target="_blank">simon.peytonjones@gmail.com</a>>> wrote:<br>
>          >>> I support acceptance.<br>
>          >>><br>
>          >>> Simon<br>
>          >>><br>
>          >>> On Wed, 30 Aug 2023 at 16:09, Arnaud Spiwack<br>
>         <<a href="mailto:arnaud.spiwack@tweag.io" target="_blank">arnaud.spiwack@tweag.io</a> <mailto:<a href="mailto:arnaud.spiwack@tweag.io" target="_blank">arnaud.spiwack@tweag.io</a>>> wrote:<br>
>          >>>> Dear all,<br>
>          >>>><br>
>          >>>> [ Proposal #583<br>
>         <a href="https://github.com/ghc-proposals/ghc-proposals/pull/583" rel="noreferrer" target="_blank">https://github.com/ghc-proposals/ghc-proposals/pull/583</a><br>
>         <<a href="https://github.com/ghc-proposals/ghc-proposals/pull/583" rel="noreferrer" target="_blank">https://github.com/ghc-proposals/ghc-proposals/pull/583</a>> ]<br>
>          >>>><br>
>          >>>> Our own Adam proposes to amend the design of the highly<br>
>         experimental OverloadedRecordUpdate extension as had been<br>
>         designed in proposal #158 [<br>
>         <a href="https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0158-record-set-field.rst" rel="noreferrer" target="_blank">https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0158-record-set-field.rst</a> <<a href="https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0158-record-set-field.rst" rel="noreferrer" target="_blank">https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0158-record-set-field.rst</a>> ] and #405 [ <a href="https://github.com/ghc-proposals/ghc-proposals/pull/405" rel="noreferrer" target="_blank">https://github.com/ghc-proposals/ghc-proposals/pull/405</a> <<a href="https://github.com/ghc-proposals/ghc-proposals/pull/405" rel="noreferrer" target="_blank">https://github.com/ghc-proposals/ghc-proposals/pull/405</a>> ].<br>
>          >>>><br>
>          >>>> Specifically, Adam proposes a modification of the type<br>
>         classes that would back the extension.<br>
>          >>>><br>
>          >>>> In the previous design the HasField class is defined as a<br>
>         lens:<br>
>          >>>><br>
>          >>>> class HasField (n :: k) r a | r n -> a<br>
>          >>>>   hasField :: r -> (a -> r, a)<br>
>          >>>><br>
>          >>>> The proposal is to replace it by two classes (slightly<br>
>         simplified)<br>
>          >>>><br>
>          >>>> class HasField (n :: k) r a | r n -> a<br>
>          >>>>   hasField :: r -> a<br>
>          >>>><br>
>          >>>> class SetField (n::k) r a | r n -> a<br>
>          >>>>   modifyField :: (a -> a) -> r -> a<br>
>          >>>>   setField :: a -> r -> a<br>
>          >>>><br>
>          >>>> This is originally motivated by some performance<br>
>         consideration: the prototype implementation of HasField as a<br>
>         lens can be very time consuming because instances of HasFields<br>
>         are generated eagerly at record definition sites, whereas the<br>
>         simple HasField instances can simply reuse the selectors already<br>
>         generated by GHC. But a lot of thoughts have been put into the<br>
>         new design, and my summary can certainly not do it justice: the<br>
>         proposal is very well argumented.<br>
>          >>>><br>
>          >>>> A point I'll make here is that the new design is actually<br>
>         parametric in the data representation of the field type.<br>
>         Something that wasn't possible in the original design.<br>
>          >>>><br>
>          >>>> This proposal is not technically backward compatible,<br>
>         because the order of argument in which OverloadedRecordUpdate<br>
>         expects the argument of setField is changed. This is not<br>
>         essential to the proposal, but this is a more consistent order<br>
>         argument with the rest of Haskell. And considering that<br>
>         OverloadedRecordUpdate is very loudly advertised as<br>
>         experimental, I recommend accepting this breakage.<br>
>          >>>><br>
>          >>>> Overall the proposal is actually more backward compatible<br>
>         with GHC 9.8 than the original design, as the HasField class is<br>
>         left unchanged.<br>
>          >>>><br>
>          >>>> Overall, the proposal looks quite reasonable to me, and<br>
>         well-argued. I recommend acceptance.<br>
<br>
<br>
<br>
-- <br>
Adam Gundry, Haskell Consultant<br>
Well-Typed LLP, <a href="https://www.well-typed.com/" rel="noreferrer" target="_blank">https://www.well-typed.com/</a><br>
<br>
Registered in England & Wales, OC335890<br>
27 Old Gloucester Street, London WC1N 3AX, England<br>
<br>
_______________________________________________<br>
ghc-steering-committee mailing list<br>
<a href="mailto:ghc-steering-committee@haskell.org" target="_blank">ghc-steering-committee@haskell.org</a><br>
<a href="https://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-steering-committee" rel="noreferrer" target="_blank">https://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-steering-committee</a><br>
</blockquote></div><br clear="all"><br><span class="gmail_signature_prefix">-- </span><br><div dir="ltr" class="gmail_signature"><div dir="ltr">Arnaud Spiwack<br>Director, Research at <a href="https://moduscreate.com" rel="noopener noreferrer" target="_blank">https://moduscreate.com</a> and <a href="https://tweag.io" rel="noopener noreferrer" target="_blank">https://tweag.io</a>.</div></div>
_______________________________________________<br>
ghc-steering-committee mailing list<br>
<a href="mailto:ghc-steering-committee@haskell.org" target="_blank">ghc-steering-committee@haskell.org</a><br>
<a href="https://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-steering-committee" rel="noreferrer" target="_blank">https://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-steering-committee</a><br>
</blockquote></div>