
As one of the authors, I'm going to engage only lightly in this conversation. Just a few comments, for the moment ➖ May require extensions (e.g. RankNTypes, ImpredicativeTypes)
on the defining side, even for a builder for the “normal” Monad (see https://github.com/ghc-proposals/ghc-proposals/pull/216#issuecomment-6007467... for an example for the previous two points)
I don't believe this to hold. Impredicative record fields are plain Haskell 2010. Should the committee follow that decision, I recommend to pick the
variant where the value does not need to be in scope, so that its mechanism is close to the normal do notation, and that you can write
import Linear (runLinear, other, stuff) … Linear.do { … }
without mucking with qualified imports or shadowing (>>). It seems odd to require the user to add ((>>), (>>=), fail) to an import list when you don’t actually mention that name anywhere.
I am, to be honest, very uncomfortable with the idea: if I explicitly
didn't import something, I don't want it to be used in my program. A
counter-argument is that types appear in desugared programs which were not
imported, so maybe I'm overreacting. But I'm still uncomfortable. And it
doesn't look like it's less of a complication than the fully-settled
business.
Overall, I personally quite prefer the record-based alternative.
On Thu, Apr 9, 2020 at 7:17 PM Joachim Breitner
Dear Committe,
Proposal:
https://github.com/tweag/ghc-proposals/blob/local-do/proposals/0000-local-do... Discussion (long, sorry): https://github.com/ghc-proposals/ghc-proposals/pull/216
Summary:
Over a year ago (on my birthday then) Arnaud created a “local do” proposal that would be a more targetted variant of RebindableSyntax, just for “do”. In June, we sent it back because a simple syntactic desugaring to records didn’t quite seem right (bad type inference).
In March, the authors can back with an alternative, which was using a Module name instead of a value of record type to indicate that monadic operations to use. This nicely solved the type system issues and meant that the translation can happen (in principle) in the parser or renamer stage. But some of us noticed that a builder record is nicer after all, and we can fix the type system issues, mostly by introducing a new concept of “fully settled type”; with analogies to TH stage restrictions.
The authors updated the proposal accordingly, but also list the alternatives in the documents.
Based on the GitHub thread we have varying opinions among the committee. Nevertheless, I think the authors have done a great and patient job so far, so we owe them a hopefully conclusive discussion.
The main question we have to decide is:
record-based or module based
Record based: ➕ A single entity one can import, reexport, even rebind ➕ A single entity that can carry the documentation ➕ One module can export multiple builders ➕ Looking forward, the builder could be dynamically constructed (i.e. a local value) ➕ Concept of fully settled may be useful elsewhere in the future and can be expanded ➖ Needs a new concept of “fully settled” that we don’t have elsewhere ➖ Initially, “fully settled” introduces staging restrictions; builder values may not be usable everywhere where they are in scope. ➖ Lots of fluff on the defining side (define a likely one-off record + a value) ➖ May require extensions (e.g. RankNTypes, ImpredicativeTypes) on the defining side, even for a builder for the “normal” Monad (see https://github.com/ghc-proposals/ghc-proposals/pull/216#issuecomment-6007467... for an example for the previous two points) ➕ Some compositionality (functions modifying builders), but ➖ not as universal as one would hope, as there is not a single builder type (different qualified monads likely use different record type) ➕ Can support “passing arguments to do” via `(monadBuilder @Maybe).do` or `(b cfg).do` (once the notion of “fully settled” is powerful enough)
Module based: ➕ Simpler to specify and understand: Only affects parsing, possibly renaming. No interactions with the type system. ➕ Works out of the box with, say, `Prelude.` as the qualifier ➕ Benefits from future improvements to the module system ➖ Would need separate syntax for “passing arguments to do”, should we want that ➕ But if we had that, it can implement the record-based approach, by passing a recoord to a suitable qualified do monad, as Iavor observes:
https://github.com/ghc-proposals/ghc-proposals/pull/216#issuecomment-5988592...
The module-based approach would additionally raises the question whether * the desugaring to M.(>>) means (>>) as provided by (some) M”, akin to how plain do notation works. * the desugaring to M.(>>) means just that (and requires (>>) to be imported as well), akin to how RebindableSyntax works
There was also a brief discussion of whether this should extend the set of operations involved to a `last` function that is used in the translation rule for a single-statement do notation, but it did not catch on.
Recommendation:
While both approaches are reasonable and have their merits, I recommend to accept the Module based approach. It supports most use-cases presented so far, in particular the Linear.do as envisioned by the authors, so it seems good enough™. Furthermore, it certainly is significantly simpler, given that it can be specified purely in terms of naming things, so we have a higher chance that this will work well with other existing and future language features.
Should the committee follow that decision, I recommend to pick the variant where the value does not need to be in scope, so that its mechanism is close to the normal do notation, and that you can write
import Linear (runLinear, other, stuff) … Linear.do { … }
without mucking with qualified imports or shadowing (>>). It seems odd to require the user to add ((>>), (>>=), fail) to an import list when you don’t actually mention that name anywhere.
Cheers, Joachim
-- Joachim Breitner mail@joachim-breitner.de http://www.joachim-breitner.de/
_______________________________________________ ghc-steering-committee mailing list ghc-steering-committee@haskell.org https://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-steering-committee