# [ghc-steering-committee] Record dot notation

Joachim Breitner mail at joachim-breitner.de
Fri Feb 7 22:37:17 UTC 2020

```Hello,

Am Freitag, den 07.02.2020, 17:13 +0000 schrieb Simon Peyton Jones via
ghc-steering-committee:
> Here are the alternatives I propose we vote on.  The first order of
> business is to check that they are all clear; and that I haven't omitted
> a worthy alternative.  Here they are:
>
> 1. Reject the proposal
>
> 2. Naked .x is illegal
>
> 3. Naked .x is a postfix operator, binding exactly
>    like application:  f r .x   means (f r).x
>
> 4. Naked .x is a postfix operator, binding more tightly
>    than application: f r .x   means   f (r.x)
>
> Under all of (2,3,4) I think we are content that
>   - (f r.x) means  (f (r.x))
>   - (.x)    means  (\r -> r.x)
>
> By "naked .x" I mean "not preceded by an identifier (e.g.
> r.x),
> or an open paren (e.g. (.x)), or a close paren (e.g. (f 3).x)

What about other non-whitespace? I assume these would also not be
naked?

"hi".x
[1,2,3].x
Foo{a = 3}.x
(☃).x

What about?

f{-comment-}x

I really would prefer a design where all these questions do not even
need to be asked…

> Let's just check everyone is happy with these alternatives.  Then we can
> vote by putting in rank order, and Joachim can run his STV algorithm.

As I said repeatedly: I am _not_ content that

(f r.x) means  (f (r.x))

as (in combination with 3, but not with 4) it introduces whitespace
sensitivity between expressions, which I would like to avoid.

So I think to have the full picture, we need the following option as
well on the ballot:

5. .x is a postfix operator, binding exactly like application,
whether it is naked or not.
(This is option 3, but without the whitespace-sensitivity.)

NB: We don’t need a variant of 4, because under rule 4, we don't need
to special-case “.x without whitespace before”. Variant 4 simply makes
.x behave like {x=1}, if I am not mistaken.

Luckily, Condorcet voting (not actually STV) allows us to add “odd”
options without affecting the result of the rest. If I am the only one
who leans towards not introducing whitespace sensitivity, this my
insisting on this being on the ballot is harmless noise.

(I wonder why we do not use the exhaustive design space overview in my
mail from Fri, 13 Dec 2019 10:14:22 +0100, where I already suggested to
vote. But I guess variants 1-5 above suffice, if nobody is asking for
any of the other three; two of them forbid (.x), which nobody seems to
advocate for. And with option 3 or 5 one kinda has to answer the
question if (.x y) should be allowed… maybe not worth the distraction.)

Anyways, now for my opinion: Assuming no more options are added, my
ranking will be

5 > 4 > 2 > 1 > 3

This puts first the two variants where .x behaves like an existing
language feature (either like function application or like record
updates), has no whitespace sensitivity, and follows existing languages
precedence (JS and OCaml, resp.).
Then the compromise solution that simply forbids putting spaces before
.x (so at least the program doesn't change semantics silently).
I dislike variant 3, which adds a _new_ special rule, and where adding
a single space can change the meaning of the program, so I rank that
last.

Cheers,
Joachim

PS, because its on my mind, and just for fun:

Under variant 3, both foo1 and foo2 typecheck, they do quite different
things (well, one loops).

data Stream a = Stream { val :: a, next :: Stream a }

foo1 f s = Stream (s.val) (foo1 (fmap f s).next)
foo2 f s = Stream (s.val) (foo2 (fmap f s) .next)

--
Joachim Breitner
mail at joachim-breitner.de
http://www.joachim-breitner.de/

```

More information about the ghc-steering-committee mailing list