[ghc-steering-committee] Records again

Eric Seidel eric at seidel.io
Tue Dec 17 01:57:46 UTC 2019


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-546645661
[2]: https://github.com/ghc-proposals/ghc-proposals/pull/282#issuecomment-547606770

> 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 at haskell.org
> https://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-steering-committee
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/ghc-steering-committee/attachments/20191216/24e06828/attachment.html>


More information about the ghc-steering-committee mailing list