[ghc-steering-committee] #216: Qualified Do again, recommendation: accept the alternative
Joachim Breitner
mail at joachim-breitner.de
Tue May 5 08:13:37 UTC 2020
Hi,
let me try to kindly rebut your points to some extent.
1. Most criticism about the module-based approach boils down to
“What if people alias unrelated modules to the same name?”
Both in the discussion on visibility (export, or also import)
and in this case.
I’d say: Nobody aliases unrelated module!
(And if some do, I don’t think they deserve to be the main deciding
factor in this decision.)
2. Error messages come up too.
But again, I don’t see any reason why GHC can’t give equally well
error messages in both cases.
Note that the desugaring _conceptually_ can happen in parsing, but
the implementation certainly won’t, and thus can give informed
error messages.
So you’d either get maybe
You have qualified the do block in … with Foo.builder, but
Foo.builder is of type Foo.Builder and the record Builder
does not have a field named (>>).
vs.
You have qualified the do block in … with Foo, but the module
Foo does not export a value named (>>).
Or, in case you are not importing enough.
You have qualified the do block in … with Foo.builder, but
you did not import the field accessor Foo.(>>).
Did you want to
add (>>) to the import list in ….
vs.
You have qualified the do block in … with Foo, and Foo exports
(>>), but you did not import Foo.(>>).
Did you want to add (>>) to the import list in ….
(or many variations of this, including helpful wording in case
the module name aliases multiple modules).
BTW, your example seemd to compares the error conditions “builder
does not provide (>>)” with “user forgot to import (>>)” – two
separate error conditions, that can both occur in both proposals.
Neither of these arguments refute your underlying preference for
records (which I would absolutely share – if we didn't need this ad-hoc
“fully settled” and odd “any type works as long as it has the right
fields”).
I think it boils down to whether the goal (records) justify the kludges
(fully settled, a desugaring that looks up some constructor K withoutusing it).
Cheers,
Joachim
(Can someone maybe just make GetField work with polytypes? Then we
woudn’t have any of this discussion, I guess.)
Am Dienstag, den 05.05.2020, 08:03 +0200 schrieb Spiwack, Arnaud:
> Sorry to have been quiet after Joachim's soliciting more input from me,
>
> Let me try to summarize why I prefer the records approach (and I think it sort of boils down to the same intuition as Simon (Peyton Jones)'s reasons):
>
> It boils down to: a record would define, in no ambiguous terms, a do notation desugaring strategy. Whereas in the module-based approach, a given do block is allowed to pick and mix different combinators from wherever it wants; even if they don't go together very well.
>
> - This makes it certain which combinators are working together. With the modules, who's to say that I am not mistakenly taking `(>>)` from a different location because I'm mixing modules together (and the module I think I'm using doesn't actually export `(>>)`)? I'd eventually find out, but it would be rather unpleasant to debug considering that I'm not even seeing `M.>>` in my code.
> - Error messages can tell me: “your builder doesn't support `>>`”, rather than telling me, “You're not importing an `M.>>`” which is a less ambiguous error.
>
> This feature, overall, makes more sense to me with records.
>
> On Mon, May 4, 2020 at 6:46 PM Tom Harding <tomjharding at live.co.uk> wrote:
> > I’m nervous to endorse any solution that requires implicit parameters generally, just because of the cognitive overhead involved in reading and understanding any code involving them. I think, for the particular problem of dynamic builders, the record approach ends up being more “idiomatic Haskell” (for my personal definition of idiomatic, of course).
> >
> > That said, I can’t deny that the solution works! Moreover, given that I don’t have a concrete example of a problem in mind, I wouldn’t want to hold up a final decision.
> >
> > Cheers,
> > Tom
> >
> > > On 4 May 2020, at 16:22, Iavor Diatchki <iavor.diatchki at gmail.com> wrote:
> > >
> > > You can define dynamic builders with the module based approach, there's an example on the GitHub thread.
> > >
> > > Iavor
> > >
> > > On Mon, May 4, 2020, 05:00 Tom Harding <tomjharding at live.co.uk> wrote:
> > > > I’ve been quiet so far because I think both outcomes are perfectly sensible, and I don’t think I have anything to add that hasn’t already been covered.
> > > >
> > > > If really pushed, I’d perhaps have a slight bias towards the record-based approach, but really only because of the future possibility of dynamically constructing builders. However, I don’t think that preference is strong enough to be worth counting - I’m happy to abstain.
> > > >
> > > > Thanks,
> > > > Tom
> > > >
> > > > > On 2 May 2020, at 10:54, Cale Gibbard <cgibbard at gmail.com> wrote:
> > > > >
> > > > > I greatly prefer the earlier module-based version of this where the
> > > > > definitions of the relevant functions are simply obtained from the
> > > > > qualified module and we don't have to talk about fully-settled types
> > > > > to explain how expressions are going to desugar. Even if it's not
> > > > > quite true in the case of GHC's internals that desugaring comes
> > > > > entirely before typechecking, I think it's really very helpful in both
> > > > > understanding the language ourselves and in explaining it to beginners
> > > > > if we can at least think about it that way. The more that the
> > > > > translation from surface syntax to core factors into a bunch of
> > > > > individually comprehensible translations, the better.
> > > > >
> > > > > On Sat, 2 May 2020 at 05:39, Joachim Breitner <mail at joachim-breitner.de> wrote:
> > > > >>
> > > > >> Dear Committee,
> > > > >>
> > > > >> it seems discussion has ebbed down. Are there any new arguments that
> > > > >> can be brought forward? Did anyone have a change of mind which would
> > > > >> bring us closer to (or farther away from) consensus? Or should we vote?
> > > > >>
> > > > >> Simon Marlow, Chris, Cale, Tom:
> > > > >> You have not stated an opinion. Do you have one?
> > > > >>
> > > > >> Cheers,
> > > > >> Joachim
> > > > >>
> > > > >> Am Mittwoch, den 22.04.2020, 12:26 +0200 schrieb Joachim Breitner:
> > > > >>> Dear Committe,
> > > > >>>
> > > > >>> trying to summarize the discussion here.
> > > > >>>
> > > > >>> The main decision seems to be: Record based or module based.
> > > > >>>
> > > > >>> Record based is preferred by:
> > > > >>> Arnaud (one of the authors), SPJ
> > > > >>>
> > > > >>> Module based is preferred by:
> > > > >>> Richard (after changing his mind), Eric, Iavor, Vitaly, Alejandro,
> > > > >>> me
> > > > >>>
> > > > >>> This is not a vote, merely a summary of sentimenss. But it seems that
> > > > >>> maybe the onus to make stronger arguments for the record-based approach
> > > > >>> is on Simon and Arnaud?
> > > > >>>
> > > > >>>
> > > > >>> Related to the module based variant, there was some discussion about
> > > > >>> whether the
> > > > >>> * desugaring should go to a “qualified name”, that is then resolved
> > > > >>> like any manually written name
> > > > >>> (i.e. could conceptually be done in the parser)
> > > > >>> * or if it should go directly a suitable “original name” of a suitable
> > > > >>> function, even if not explicitly imported
> > > > >>> (i.e. could conceptually be done in the renamer, but not the parser)
> > > > >>>
> > > > >>> I initially advocated for the latter, arguing with a “you shall not
> > > > >>> have to import stuff you do not write explicitly” rule.
> > > > >>> But Simon’s recent argument that
> > > > >>>
> > > > >>> import qualified Monad as M
> > > > >>>
> > > > >>> (i.e. _with_ qualification, but _without_ an import list) will give the
> > > > >>> developer a good user experience, and if they try to do things like
> > > > >>>
> > > > >>> import Monad as M (runMonad)
> > > > >>> … M.do …
> > > > >>>
> > > > >>> then, well, they shouldn’t. So I am happy to advocate for the module
> > > > >>> based approach with the “must be in scope” rule. But maybe we should
> > > > >>> keep the focus more on the fundamental question above.
> > > > >>>
> > > > >>>
> > > > >>>
> > > > >>> We could keep in mind that eventually, people will ask for M.if; M.[
> > > > >>> and other “qualified syntax”. But it seems that that will work equally
> > > > >>> well with either choice here.
> > > > >>>
> > > > >>> Cheers,
> > > > >>> Joachim
> > > > >>>
> > > > >>>
> > > > >> --
> > > > >> Joachim Breitner
> > > > >> mail at joachim-breitner.de
> > > > >> http://www.joachim-breitner.de/
> > > > >>
> > > > >>
> > > > >> _______________________________________________
> > > > >> ghc-steering-committee mailing list
> > > > >> ghc-steering-committee at haskell.org
> > > > >> https://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-steering-committee
> > > > > _______________________________________________
> > > > > ghc-steering-committee mailing list
> > > > > ghc-steering-committee at haskell.org
> > > > > https://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-steering-committee
> > > >
> > > > _______________________________________________
> > > > ghc-steering-committee mailing list
> > > > ghc-steering-committee at haskell.org
> > > > https://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-steering-committee
> > > >
> >
> > _______________________________________________
> > ghc-steering-committee mailing list
> > ghc-steering-committee at haskell.org
> > https://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-steering-committee
>
> _______________________________________________
> ghc-steering-committee mailing list
> ghc-steering-committee at haskell.org
> https://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-steering-committee
--
Joachim Breitner
mail at joachim-breitner.de
http://www.joachim-breitner.de/
More information about the ghc-steering-committee
mailing list