[ghc-steering-committee] RecordDotSyntax: please express a view
Joachim Breitner
mail at joachim-breitner.de
Fri Dec 13 09:14:22 UTC 2019
Hi,
unsurprisingly, Wadler’s law holds also within the committee. It looks
like we have to accept that this one will not likely be solved by
consensus (at least not “enthusiastic consensus”). But that is fine:
The main point of the committee is to make _a_ decision, and we can
vote and probably all live with the outcome.
I’m not calling a vote yet (I’ll leave that to Simon when he feels that
likely no new insights are going to emerge), but would like to outline
the procedure.
We could do a simple majority yes/no vote on the proposal as it stands.
But I believe we can do better, by collecting all (reasonable) options
that have been discussed, and doing a ranked voting.
At the risk of secretarysplaining I’d like to point out that that
voting tends to favor more widly acceptable outcomes: If 35% want .foo
to be the selector, 30% want .foo to be a selection even with spaces on
the left, and 25% are prefer to be conservative and forbid free-
standing .foo for now, then it may be that that last option wins, as
the most consensusable, wins.
So if we do it this way, you should be able to express your genuine
ranking preference, and not worry about strategic voting.
So what options are on the table?
I tried to find a small set of representative examples that explore all
contentious corners of the design space, and came up with this:
r.field
f x.field y
f x .field y
f x (.field) y
f x (.field y)
I believe our reasonable options are (and there are many…)
Reject:
r.field = \a -> r (field a)
f x.field y = \a -> f x (field y a)
f x .field y = \a -> f x (field y a)
f x (.field) y = f x (\a -> a . field) y
f x (.field y) = f x (\a -> a . field y)
OnlySelection:
r.field = getField @"field" r
f x.field y = f (x.field) y
f x .field y -- NOT ALLOWED
f x (.field) y -- NOPE
f x (.field y) -- NAY
SectionSelector:
r.field = getField @"field" r
f x.field y = f (x.field) y
f x .field y -- VERBOTEN!
f x (.field) y = f x (\r->r.field) y
f x (.field y) -- BAD!
PlainSelector: -- this is the proposal as it stands, I believe
r.field = getField @"field" r
f x.field y = f (x.field) y
f x .field y = f x (\r->r.field) y
f x (.field) y = f x (\r->r.field) y
f x (.field y) = f x ((\r->r.field) y) = f x (field y) -- !
Ocaml:
r.field = getField @"field" r
f x.field y = f (x.field) y
f x .field y = f (x.field) y
f x (.field) y -- NOT ALLOWED
f x (.field y) -- CAN’T DO THAT
Ocaml+Section:
r.field = getField @"field" r
f x.field y = f (x.field) y
f x .field y = f (x.field) y
f x (.field) y = f (\r->r.field) y
f x (.field y) -- NO NO NO
JS:
r.field = getField @"field" r
f x.field y = ((f x).field) y
f x .field y = ((f x).field) y
f x (.field) y -- IMPOSSIBLE!
f x (.field y) -- STOP IT PLEASE!
JS+Section:
r.field = getField @"field" r
f x.field y = ((f x).field) y
f x .field y = ((f x).field) y
f x (.field) y = f x (\r->r.field) y
f x (.field y) = f x (\r->(r.field) y)
(Ocaml = . binds more tightly than function application to the left,
JS = .foo has same precendence and associativity as function
application.)
In writing this I noticed that `f x (.field y)` hasn’t been given much
discussion, and it seems to only really make sense in the JS-inspired
variant where chaining becomes possible, and (.field y) is the
“obvious” section syntax for the chaining use of .field. It should
probably be prohibited in the variants that want (.field) to be
parenthesized.
Am I missing any reasonable point in the design space?
Do I need to add more examples to the list of representative examples?
I am not including the option to print a warning for misleading code
(e.g. if `f x.field y = ((f x).field) y`), as that is a separate idea
that applies to more than just records. But if people want to express,
say, “JS, but only if we get such a warning”, we can add these variants
to the ballot.
Cheers,
Joachim
--
Joachim Breitner
mail at joachim-breitner.de
http://www.joachim-breitner.de/
More information about the ghc-steering-committee
mailing list