[ghc-steering-committee] #512: NoFieldSelectors as datatype annotation, Recommendation: reject

Adam Gundry adam at well-typed.com
Fri Dec 9 08:18:21 UTC 2022


On 09/12/2022 07:38, Simon Peyton Jones wrote:
>     It seems to me that the only motivation for this proposal is for
>     Template Haskell generated code 
> 
> 
> I don't think so.  Michael suggested another
> 
>     Another motivation: today it's generally considered Bad Practice to
>     use record syntax for the constructors of datatypes with
>     alternatives, because this generates partial field accessors. With
>     NoFieldSelectors, we can avoid this, but at the cost of turning off
>     field selector generation for the entire module, which we might not
>     want. Being able to control field selector generation on a
>     per-datatype level lets you use this trick while keeping other
>     "normal" records the same.
> 
> I think this proposal is generally a good idea.

I agree with Simon here: the motivation for this proposal is wider than 
just with TH. It will be useful to be able to explore designs where a 
single module includes one record datatype with selectors, and other 
datatypes that use the same field names but not selectors. Those might 
be TH-generated, but need not be in general.

Moreover, I think it would be problematic to have features that are 
available only via TH splices and that cannot be translated to the 
underlying declarations. As a user I expect to be able to expand spliced 
declarations, and some users rely on this (e.g. to support 
cross-compilation scenarios where TH support is tricky).


> If we have NoRecrodSelectors at all we should have it on a
> per-data-type basis.

Agreed. But what about per-field or per-constructor? The proposal allows 
these but I'm not convinced we need more than per-datatype, and that 
would reduce complexity.


> I am exercised about the modifiers problem  If we had modifiers we'd 
> definitely use them.  Using pragmas temporarily adds friction because 
> we'll have to go through deprecation cycles to get rid of them.
> 
> I think we should accept the proposal, but also proactively seek 
> implementation support for modifiers.   If we push hard maybe we can get 
> modifiers in time not to have to go round the houses with pragmas.
> 
> The only thing I'd like to add to the proposal is the specific modifier 
> design.  What is the modifier name?  From which module is the modifier 
> exported.  That way when we get modifiers we don't have to start a new 
> debate.

I think there is a debate to be had about whether modifiers are really 
the best approach in general. Is the lack of motivation to implement 
then a sign that we don't really need them?


> On Thu, 8 Dec 2022 at 17:01, Arnaud Spiwack <arnaud.spiwack at tweag.io 
> <mailto:arnaud.spiwack at tweag.io>> wrote:
> 
>     It seems to me that the only motivation for this proposal is for
>     Template Haskell generated code. So maybe we can imagine an
>     alternative that is purely in Template Haskell, without any syntax.
>     Which would avoid the concerns about parsing pragmas*. Maybe there
>     is room, in this space, for a generic mechanism, but I don't think
>     that we'd need this: it makes sense to let the Template Haskell
>     slice decide if a record it defines generates selectors or not.
> 
>     That being said, I'm personally ok with the proposal as it stands, I
>     think it makes sense. But it's likely that a pure Template Haskell
>     solution may be both more forward compatible and easier to implement
>     (at least, based on Vlad estimate, who knows this part of the code,
>     I'm inclined to believe so). As there doesn't seem to be any
>     particular motivation beyond Template Haskell, I'd be ok if we made
>     this counter-proposal.
> 
>     I don't think counterargument 4 is something we can oppose: it is
>     theoretically possible to define the doppelgänger record in a
>     separate module, but we know it won't happen. Matt Parsons mentions
>     the Esqueleto library, it is obvious that the library will prefer
>     using a silly name for record fields  rather than ask its users to
>     move definitions to another module and the library will be right: it
>     is less obnoxious.
> 
>     All in all, I think that the proposal is quite reasonable, and would
>     open space in the design of Template-Haskell based libraries.
> 
>     * For the record, I don't think that we can claim that pragmas can
>     be ignored semantically. The OVERLAPPING pragma is a
>     counter-example. Maybe more acutely: the LANGUAGE pragma. So I don't
>     agree with counterargument 3.
> 
>     On Wed, 30 Nov 2022 at 22:18, Adam Gundry <adam at well-typed.com
>     <mailto:adam at well-typed.com>> wrote:
> 
>         On 30/11/2022 20:37, Joachim Breitner wrote:
>          > Hi,
>          >
>          > Am Mittwoch, dem 30.11.2022 um 19:28 +0000 schrieb Adam Gundry:
>          >> What do you think?
>          >
>          > my initial feeling about `language … where …` is that it is a
>         modifer
>          > of sorts, however
>          >   * with a syntax that may not scale well (hard to target
>         anything
>          >     but a whole set of declarations)
>          >   * looks like it could support any kind of language
>         extension, when
>          >     it probably doesn’t make sense for all of them.
>          > so may not gain much over implementing (parts) of the
>         modifier syntax.
> 
>         Well, I find it hard to imagine really needing to enable an
>         extension
>         for anything smaller than a declaration group. On the other
>         hand, I not
>         infrequently want to enable particular extensions only for a few
>         specific definitions (AllowAmbiguousTypes comes to mind).
> 
>         As I understand it, modifiers need to be type-checked before
>         they have
>         meaning assigned. This presumably means they cannot change the
>         behaviour
>         of the parser, whereas an explicit "language ... where ..."
>         construct
>         could do so. And I don't think modifiers can scope over a
>         declaration
>         group, only a single declaration?
> 
>         I agree that we wouldn't necessarily support *all* language
>         extensions
>         locally, but I think the list for which this fundamentally does
>         not make
>         sense is relatively short (the main ones that come to mind are
>         import-related extensions such as ExplicitNamespaces). Others
>         might be
>         hard to specify/implement (e.g. Safe Haskell seems tricky) but
>         we could
>         simply not support them locally.
> 
> 
>          > ...
>          >
>          > Or we revive local modules, and use that as a then natural way of
>          > scoping language pragmas…
> 
>         There's clearly a relationship to local modules, but that seems
>         like
>         more complexity than we need for the problem at hand. I don't
>         see why we
>         shouldn't add "language ... where ..." now, then potentially later
>         support local (or top-level!) modules with
> 
>             language Blah where
>               module M where
>                 ...
> 
>         After all, {-# LANGUAGE #-} pragmas violate the principle that
>         pragmas
>         shouldn't change semantics. ;-)
> 
>         Cheers,
> 
>         Adam
> 


-- 
Adam Gundry, Haskell Consultant
Well-Typed LLP, https://www.well-typed.com/

Registered in England & Wales, OC335890
27 Old Gloucester Street, London WC1N 3AX, England



More information about the ghc-steering-committee mailing list