<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class=""><br class=""><div><br class=""><blockquote type="cite" class=""><div class="">On Apr 13, 2020, at 12:40 PM, Simon Marlow <<a href="mailto:marlowsd@gmail.com" class="">marlowsd@gmail.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div dir="ltr" class=""><div class="">This seems like it could be thought of as a special case of record selection. (apologies if this has been discussed before, I haven't read the whole discussion thread.)</div><div class=""><br class=""></div><div class="">The syntax is even reminiscent of record selection. But unlike selecting a single field, we're selecting a bunch of fields and using them to desugar a do expression.This makes me wonder: would it be possible to handle the typing by generating HasField constraints for (>>=) and friends? And would that avoid needing to talk about "fully settled" types?</div></div></div></blockquote><div><br class=""></div><div>Tempting, but no: the HasField mechanism fails for polymorphic record fields, which we desperately need here. :(</div><div><br class=""></div><div>Richard</div><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class=""><br class=""></div><div class="">Cheers</div><div class="">Simon<br class=""></div><div class=""><br class=""></div></div><br class=""><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Thu, 9 Apr 2020 at 18:17, Joachim Breitner <<a href="mailto:mail@joachim-breitner.de" class="">mail@joachim-breitner.de</a>> wrote:<br class=""></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Dear Committe,<br class="">
<br class="">
Proposal: <br class="">
<a href="https://github.com/tweag/ghc-proposals/blob/local-do/proposals/0000-local-do.rst" rel="noreferrer" target="_blank" class="">https://github.com/tweag/ghc-proposals/blob/local-do/proposals/0000-local-do.rst</a><br class="">
Discussion (long, sorry):<br class="">
<a href="https://github.com/ghc-proposals/ghc-proposals/pull/216" rel="noreferrer" target="_blank" class="">https://github.com/ghc-proposals/ghc-proposals/pull/216</a><br class="">
<br class="">
<br class="">
Summary:<br class="">
<br class="">
Over a year ago (on my birthday then) Arnaud created  a “local do”<br class="">
proposal that would be a more targetted variant of RebindableSyntax,<br class="">
just for “do”. In June, we sent it back because a simple syntactic<br class="">
desugaring to records didn’t quite seem right (bad type inference).<br class="">
<br class="">
In March, the authors can back with an alternative, which was using a<br class="">
Module name instead of a value of record type to indicate that monadic<br class="">
operations to use. This nicely solved the type system issues and meant<br class="">
that the translation can happen (in principle) in the parser or renamer<br class="">
stage. But some of us noticed that a builder record is nicer after all,<br class="">
and we can fix the type system issues, mostly by introducing a new concept<br class="">
of “fully settled type”; with analogies to TH stage restrictions.<br class="">
<br class="">
The authors updated the proposal accordingly, but also list the alternatives<br class="">
in the documents.<br class="">
<br class="">
Based on the GitHub thread we have varying opinions among the committee.<br class="">
Nevertheless, I think the authors have done a great and patient job so far, so<br class="">
we owe them a hopefully conclusive discussion.<br class="">
<br class="">
The main question we have to decide is:<br class="">
<br class="">
    record-based   or    module based<br class="">
<br class="">
<br class="">
Record based:<br class="">
 ➕ A single entity one can import, reexport, even rebind<br class="">
 ➕ A single entity that can carry the documentation<br class="">
 ➕ One module can export multiple builders<br class="">
 ➕ Looking forward, the builder could be dynamically constructed<br class="">
   (i.e. a local value)<br class="">
 ➕ Concept of fully settled may be useful elsewhere in the future<br class="">
   and can be expanded<br class="">
 ➖ Needs a new concept of “fully settled” that we don’t have elsewhere<br class="">
 ➖ Initially, “fully settled” introduces staging restrictions;<br class="">
   builder values may not be usable everywhere where they are in scope.<br class="">
 ➖ Lots of fluff on the defining side<br class="">
   (define a likely one-off record + a value)<br class="">
 ➖ May require extensions (e.g. RankNTypes, ImpredicativeTypes)<br class="">
   on the defining side, even for a builder for the “normal” Monad<br class="">
   (see <a href="https://github.com/ghc-proposals/ghc-proposals/pull/216#issuecomment-600746723" rel="noreferrer" target="_blank" class="">https://github.com/ghc-proposals/ghc-proposals/pull/216#issuecomment-600746723</a><br class="">
   for an example for the previous two points)<br class="">
 ➕ Some compositionality (functions modifying builders), but<br class="">
 ➖ not as universal as one would hope, as there is not a single builder type<br class="">
   (different qualified monads likely use different record type)<br class="">
 ➕ Can support “passing arguments to do” via `(monadBuilder @Maybe).do`<br class="">
   or `(b cfg).do`<br class="">
   (once the notion of “fully settled” is powerful enough)<br class="">
<br class="">
Module based:<br class="">
 ➕ Simpler to specify and understand:<br class="">
   Only affects parsing, possibly renaming. No interactions with the type system.<br class="">
 ➕ Works out of the box with, say, `Prelude.` as the qualifier<br class="">
 ➕ Benefits from future improvements to the module system<br class="">
 ➖ Would need separate syntax for “passing arguments to do”, should we want that<br class="">
 ➕ But if we had that, it can implement the record-based approach, by passing a<br class="">
   recoord to a suitable qualified do monad, as Iavor observes:<br class="">
   <a href="https://github.com/ghc-proposals/ghc-proposals/pull/216#issuecomment-598859245" rel="noreferrer" target="_blank" class="">https://github.com/ghc-proposals/ghc-proposals/pull/216#issuecomment-598859245</a><br class="">
<br class="">
The module-based approach would additionally raises the question whether<br class="">
 * the desugaring to M.(>>) means (>>) as provided by (some) M”,<br class="">
   akin to how plain do notation works.<br class="">
 * the desugaring to M.(>>) means just that (and requires (>>) to be imported as well),<br class="">
   akin to how RebindableSyntax works<br class="">
<br class="">
<br class="">
There was also a brief discussion of whether this should extend the set<br class="">
of operations involved to a `last` function that is used in the<br class="">
translation rule for a single-statement do notation, but it did not<br class="">
catch on.<br class="">
<br class="">
<br class="">
Recommendation:<br class="">
<br class="">
While both approaches are reasonable and have their merits, I recommend<br class="">
to accept the Module based approach. It supports most use-cases<br class="">
presented so far, in particular the Linear.do as envisioned by the<br class="">
authors, so it seems good enough™.<br class="">
Furthermore, it certainly is significantly simpler, given that it can<br class="">
be specified purely in terms of naming things, so we have a higher<br class="">
chance that this will work well with other existing and future language<br class="">
features.<br class="">
<br class="">
Should the committee follow that decision, I recommend to pick the<br class="">
variant where the value does not need to be in scope, so that its<br class="">
mechanism is close to the normal do notation, and that you can write<br class="">
<br class="">
 import Linear (runLinear, other, stuff)<br class="">
 …<br class="">
   Linear.do { … }<br class="">
<br class="">
without mucking with qualified imports or shadowing (>>). It seems odd<br class="">
to require the user to add ((>>), (>>=), fail) to an import list when<br class="">
you don’t actually mention that name anywhere.<br class="">
<br class="">
<br class="">
<br class="">
<br class="">
Cheers,<br class="">
Joachim<br class="">
<br class="">
<br class="">
-- <br class="">
Joachim Breitner<br class="">
  <a href="mailto:mail@joachim-breitner.de" target="_blank" class="">mail@joachim-breitner.de</a><br class="">
  <a href="http://www.joachim-breitner.de/" rel="noreferrer" target="_blank" class="">http://www.joachim-breitner.de/</a><br class="">
<br class="">
<br class="">
_______________________________________________<br class="">
ghc-steering-committee mailing list<br class="">
<a href="mailto:ghc-steering-committee@haskell.org" target="_blank" class="">ghc-steering-committee@haskell.org</a><br class="">
<a href="https://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-steering-committee" rel="noreferrer" target="_blank" class="">https://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-steering-committee</a><br class="">
</blockquote></div>
_______________________________________________<br class="">ghc-steering-committee mailing list<br class=""><a href="mailto:ghc-steering-committee@haskell.org" class="">ghc-steering-committee@haskell.org</a><br class="">https://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-steering-committee<br class=""></div></blockquote></div><br class=""></body></html>