[ghc-steering-committee] Record dot notation
Cale Gibbard
cgibbard at gmail.com
Tue Feb 11 17:28:31 UTC 2020
Since I seem to be of the opinion that this wouldn't be a good
inclusion while most everyone else is more convinced that *something*
along these lines is needed or desirable, perhaps someone can explain
what sort of code they'd like to write which this makes more pleasant
in any regard? I've seen a lot of negotiation over the potential
meaning of frustrating-to-visually-parse terms, without much
discussion of why terms of those forms are desirable in the first
place. What messy code are we trying to tidy up here?
I honestly believe that the status quo is preferable to adding more
overloading of "." -- the main problems with the record syntax from my
perspective being the fact that it automatically-defines partial
functions in the case where you have multiple data constructors
(crashing is bad), and the fact that perhaps incomplete record
construction should simply be an error rather than a warning, because
it's practically never been useful, and in the rare cases where one
actually might want it, it's not onerous to explicitly write an error
in.
Of course, you get no row polymorphism that way, but if we actually
want row polymorphism, why aren't we considering something like a new
kind for row variables, and Ermine's row partition constraints? I'm
not sure that fiddling with this bit of syntax sugar atop algebraic
data types and adding more sugar on top of it can actually get us to a
pleasant/satisfying system for row polymorphism.
Maybe it's bought us the right to use the same record field names in
multiple places, but not too much else, and any way of doing that will
come at the cost of being able to figure out what the types of things
are by looking at the fields which are present, which is an important
aspect of being able to typecheck code in one's head. If all I get for
making it harder to mentally typecheck code is the ability to reuse
field names, it doesn't seem like a very good deal to me. I'd rather
continue to disambiguate those with prefixes so that when I come
across a field selection, I can tell the precise type of the record
immediately. Admittedly, HasField gives you some polymorphism, but
without most of the usual conveniences of extensible records, and in
most real cases, you'd want an actual type class anyway, to tell the
users of your code that the abstraction is not accidental.
If it bought me substantially more than that, maybe I could be
convinced. There are some real-world settings where one would plainly
want extensible records, but they tend to be messy situations where
one has somewhat-arbitrary combinations of a large number of potential
columns. With this HasField approach, you still need to explicitly
define new data types for each combination you want, even if there's a
little automatic sugar for abstracting over them.
But even after all that discussion, I don't see why it is that we'd
want *this* particular syntax for it, which really doesn't look like
it fits in with the rest of the language very well. Function
compositions are common and there are a lot of dots in most of the
code I've ever worked on already -- if not for function composition,
then for composition in the Control.Category sense. The thought of
mixing some partially applied record field selectors in there at the
same time makes my eyes water (qualified names are already kind of
annoying). And if this is not about the concrete syntax of using dot
for yet another thing, then what is it about? We presumably already
have reasonably convenient ways of expressing everything here, don't
we?
I'm baffled.
On Tue, 11 Feb 2020 at 05:33, Simon Peyton Jones via
ghc-steering-committee <ghc-steering-committee at haskell.org> wrote:
>
> In my message on 7th I said that the first step would be to identify the alternatives on which we could subsequently vote. Since then
>
> Joachim suggested (5)
> I suggested a refinement to that (yesterday), treating r.x as a lexeme like M.x, but otherwise like (5)
>
>
>
> Does anyone have any other alternatives they actively want to see on the list? Then I’ll gather them together and invite you to express your votes.
>
>
>
> Simon
>
>
>
> From: Spiwack, Arnaud <arnaud.spiwack at tweag.io>
> Sent: 11 February 2020 07:59
> To: Simon Peyton Jones <simonpj at microsoft.com>
> Cc: ghc-steering-committee at haskell.org
> Subject: Re: [ghc-steering-committee] Record dot notation
>
>
>
> I'm swaying back and forth, but I'll go with my gut feeling:
>
> 4>3>2>1
>
>
>
> On Fri, Feb 7, 2020 at 6:13 PM Simon Peyton Jones via ghc-steering-committee <ghc-steering-committee at haskell.org> wrote:
>
> Colleagues
>
> I've been slow on the records front; apologies.
>
> I think Joachim is right: we've discussed a lot of options, but in the
> end much of this is a judgement call with no perfect answers, and it
> now seems simplest to express our judgement through voting. I think
> we are all keen to decide this and move on.
>
> Proposal: https://github.com/shayne-fletcher-da/ghc-proposals/blob/record-dot-syntax/proposals/0000-record-dot-syntax.md
> Lengthy discussion: https://github.com/ghc-proposals/ghc-proposals/pull/282
>
> 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)
>
> We could re-open more of this, but I'd prefer to keep it to 1-4.
>
> 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.
>
>
> I'm the shepherd for this proposal, so let me add my recommendations.
>
> I strongly urge that we do not adopt (1); that is, we accept the
> proposal in some form. I have been unhappy with GHC's story for
> records for two decades. (E.g. Lightweight extensible records for
> Haskell, Haskell Workshop, Paris 1999.) But the design space is so
> complicated that we never found something that felt "obviously right".
> So we did nothing drastic, and I think that was right.
>
> But there was incremental progress, sketched here:
> https://gitlab.haskell.org/ghc/ghc/wikis/records/overloaded-record-fields
>
> * DuplicateRecordFields lets you have multiple records with the
> same field name.
> * The HasField class lets us define overloaded record selection
> and update functions.
>
> The proposal we are now discussing has no type-system component;
> it is *only* about syntactic sugar, allowing you to use dot-notation
> for field selection.
>
> Various extensions about syntax for update were discussed, but no
> longer form part of the proposal; what is left is the core, which
> has a particularly high benefit/cost ratio.
>
> Now, judgements may differ about the importance of syntactic sugar --
> that's why we have a committee with a diversity of views -- but I
> believe that dot-notation for record selection is super-important.
> I've wanted it for ages. Every other language has it. We have
> accepted other syntactic sugar with much lower utility. And
> the dot is already a special case, via qualified names.
>
> I respect the fact that others may differ, but I really think
> think this is worth it. It would be a crying shame to reject
> this. Unlike Chris, I don't think anything better is going to
> emerge, however long we wait.
>
> I am more relaxed about 2/3/4. Personally I hate (4) because
> I don't like *any* notation in which something binds more tightly
> than function application. e.g. I cordially dislike (f K {x=3})
> meaning (f (K {x=3})).
>
> My preference is for (3), which allows record selection with
> spaces (which some argue for). But (2) represents at most a lost
> opportunity, not a bad thing.
>
> Thanks
>
> Simon
>
> _______________________________________________
> ghc-steering-committee mailing list
> ghc-steering-committee at haskell.org
> https://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-steering-committee
>
> _______________________________________________
> ghc-steering-committee mailing list
> ghc-steering-committee at haskell.org
> https://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-steering-committee
More information about the ghc-steering-committee
mailing list