
Simon,
I'm happy with letting you choose the syntax. You've got more stake in all
this than any of us, and this is a conversation which can't end without
someone having a final word.
Let's give ourselves a deadline, after which whatever we've decided (for
example by letting Simon choose :-) ) isn't up to debate anymore.
Then we can go back to deciding on the specifics of the proposal.
On Tue, Dec 17, 2019 at 2:58 AM Eric Seidel
On Mon, Dec 16, 2019, at 18:48, Simon Peyton Jones via ghc-steering-committee wrote:
Assuming that we want to accept some version, *I'd like to propose that we adopt the idea that `f r.x` means `f (r.x)`*, and not the record selection `(f r).x`
I would be content with either parse. The thing I found compelling about Joachim's suggestion was that it makes the syntax around `.` a bit less whitespace-sensitive.
My concerns have been mostly around the meaning of a bare `.x`, as in
f r.x .y
It seems like the committee is largely in agreement that a bare `.x` should not desugar to `\r -> r.x`. My reasoning is similar to what Chris Done[1] and Chris Smith[2] have articulated on the GitHub thread, namely that you should be able to split a deep record access across multiple lines without resorting to syntactic contortions like
f (r.x ).y
So, if we are all content with `f r.x` meaning `f (r.x)` and with a bare `.x` not desugaring to `\r -> r.x`, there's still a question of how to parse
f r.x .y
Does it parse as
f ((r.x) -- (A) .y)
or
(f (r.x)) -- (B) .y
or
ERROR -- (C)
(A) would mean that field access binds more tightly than function application. I think the result is intuitive, but the only precedent we have for binding tighter than function application is record syntax, which is widely criticized (including by myself).
(B) means the opposite, application binds more tightly than field access. I'm not sure how I feel about this. It seems prone to misinterpretation, but perhaps we can learn to adapt to it (ironically) the way we've adapted to record syntax.
(C) means that function application and field access don't associate. I believe Richard suggested this previously, and I think it's actually a pretty sensible solution. If you want to combine the two, you must disambiguate for us. This means that I'd have to write my example as
f (r.x .y)
which still looks perfectly fine to me.
Eric
[1]: https://github.com/ghc-proposals/ghc-proposals/pull/282#issuecomment-5466456... [2]: https://github.com/ghc-proposals/ghc-proposals/pull/282#issuecomment-5476067...
Joachim floated the `(f r).x` idea recently and Richard supported him. I consulted the authors who said "Interestingly, the very first version of the prototype implemented exactly that. That behaviour surprised the heck out of everyone (including you) and we were quickly and overwhelmingly convinced that it was the wrong parse and updated the proposal accordingly." I had a long conversation with Richard, who (I think) finds both alternatives acceptable.
I agree strongly with the authors; I think `(f r).x` would be horrible, and would vote against such a proposal. So, in the interests of making progress, I recommend that we adopt the `f (r.x)` parse. Talking to Richard I realise that a lot depends on your starting point:
1. I regard `M.N.x` and `r.x.y` as a single token, where `.` is punctuation. Space is always significant for dot; `M . x` is quite different to `M.x`. Another example is the unbounded enumeration `[Z ..]` where you must put the space; if you write `[Z..]` you'll get the dot-operator imported from module Z. From this point of view, Haskell's use of `(.)` as an infix operator for composition is an aberration. And parsing `f r.x` as `f (r.x)` is consistent with our parse of `f M.x`.
1. An alternative point of view is to regard `(.)` as a fully fledged operator, and all the stuff about qualified names, enumerations and so on, as a sad aberration. Under this point of view, record selection just makes the aberration worse. I realise that one reason I want the `f (r.x)` parse so strongly is my previously-implicit espousal of (A); perhaps making that explicit will help frame the conversation. I’m also very un-keen on making `r.x` illegal, which is another alternative in theory.
TL;DR. Does anyone (who wants to accept the proposal in some form) seriously oppose the `f (r.x)` parse for `f r.x`? I hope that it'll be at least acceptable to everyone, and we can more on.
Thanks
Simon
_______________________________________________ ghc-steering-committee mailing list ghc-steering-committee@haskell.org https://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-steering-committee
_______________________________________________ ghc-steering-committee mailing list ghc-steering-committee@haskell.org https://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-steering-committee