[ghc-steering-committee] RecordDotSyntax: please express a view
Eric Seidel
eric at seidel.io
Wed Dec 11 03:27:57 UTC 2019
On Tue, Dec 10, 2019, at 09:27, Simon Peyton Jones via ghc-steering-committee wrote:
> You may be arguing that naked `.x` is a *postfix operator*, rather like
> factorial when we write 5!.
I brought this up at some point during the discussion. Treating a bare `.x` as a postfix operator feels very natural to me, and then `(.x)` would be a natural way to refer to the operator itself.
I'm not at all sure what the precedence of such an operator should be, however. When I see an example like
> f a .b c .d e
I want to parse it (if at all) as
> f (a .b) (c .d) e
rather than
> ((f a).b c).d e
However, when confronted with
> xs .map double
> .filter isEven
> .map square
I instinctively want to flip the precedences and parse it as
> (((xs.map) double).filter isEven).map square
What a difference some newlines (or is it the real names?) makes!
Perhaps some more examples will be instructive. Another example that came up was deeply nested field accesses that don't fit onto a single line.
> x.foo
> .bar
> .baz
This will be parsed as
> ((x.foo).bar).baz
regardless of precedence, as there is no function application. What if we add one?
> f x.foo
> .bar
> .baz
If function application binds more tightly than field selection, this would parse as
> ((f x.foo).bar).baz
If you instead wanted
> f (x.foo.bar.baz)
you could add parens
> f (x.foo
> .bar
> .baz)
which still looks reasonable to me.
So I think I would be happy with bare `.lbl` being a postfix operator that binds less tightly than function application.
More information about the ghc-steering-committee
mailing list