From simonpj at microsoft.com Fri Feb 7 17:13:03 2020 From: simonpj at microsoft.com (Simon Peyton Jones) Date: Fri, 7 Feb 2020 17:13:03 +0000 Subject: [ghc-steering-committee] Record dot notation Message-ID: 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 From iavor.diatchki at gmail.com Fri Feb 7 19:06:22 2020 From: iavor.diatchki at gmail.com (Iavor Diatchki) Date: Fri, 7 Feb 2020 11:06:22 -0800 Subject: [ghc-steering-committee] Record dot notation In-Reply-To: References: Message-ID: Those seem like reasonable options to me. I think my preference would be: 2,4,3,1. My justification is that I find the naked selectors a bit odd, but if we are going to have them I find (4) a bit easier to explain: the rule is that record selection has higher precedence than function application, and white space does not need to be discussed at all. I agree that this might not be the most elegant of proposals, but having recently tried to use the `getField` class method in anger without the syntactic sugar, I think that my code would be a lot more readable with this extension than without. -Iavor On Fri, Feb 7, 2020 at 9:13 AM Simon Peyton Jones via ghc-steering-committee 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 > -------------- next part -------------- An HTML attachment was scrubbed... URL: From cma at bitemyapp.com Fri Feb 7 19:47:43 2020 From: cma at bitemyapp.com (Chris Allen) Date: Fri, 7 Feb 2020 13:47:43 -0600 Subject: [ghc-steering-committee] Record dot notation In-Reply-To: References: Message-ID: 1, 2, (and that's it) On 2/7/20 1:06 PM, Iavor Diatchki wrote: > Those seem like reasonable options to me. > > I think my preference would be:  2,4,3,1. > > My justification is that I find the naked selectors a bit odd, but if > we are going to have them I find (4) > a bit easier to explain:  the rule is that record selection has higher > precedence than function application, > and white space does not need to be discussed at all. > > I agree that this might not be the most elegant of proposals, but > having recently tried to use the `getField` > class method in anger without the syntactic sugar, I think that my > code would be a lot more readable with this extension > than without. > > -Iavor > > > > > > > > On Fri, Feb 7, 2020 at 9:13 AM Simon Peyton Jones via > ghc-steering-committee > 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 -------------- next part -------------- An HTML attachment was scrubbed... URL: From mail at joachim-breitner.de Fri Feb 7 22:37:17 2020 From: mail at joachim-breitner.de (Joachim Breitner) Date: Fri, 07 Feb 2020 23:37:17 +0100 Subject: [ghc-steering-committee] Record dot notation In-Reply-To: References: Message-ID: 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/ From cgibbard at gmail.com Fri Feb 7 23:41:30 2020 From: cgibbard at gmail.com (Cale Gibbard) Date: Fri, 7 Feb 2020 18:41:30 -0500 Subject: [ghc-steering-committee] Record dot notation In-Reply-To: References: Message-ID: 1 > 2 > 3 > 4 I don't really understand the need for this syntax sugar. It seems to optimise already-short expressions by a constant factor in a way that makes their meaning harder to grasp. Think about how much effort people have spent trying to understand what .x ought to mean and how it should be parsed here, and multiply that by all the users of the language who are actually going to have to deal with occurrences of it and wonder what's going on. The period character is already too overloaded in Haskell's syntax imo, and I don't really see why we should need it when there are plenty of reasonable other options for expressing these programs, including the option of no further syntax sugar at all. The fact that other languages use that syntax isn't really an argument that it's right for Haskell, which is very different from those languages in countless other ways already. On Fri, 7 Feb 2020 at 17:37, Joachim Breitner wrote: > > 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/ > > > _______________________________________________ > ghc-steering-committee mailing list > ghc-steering-committee at haskell.org > https://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-steering-committee From bravit111 at gmail.com Mon Feb 10 08:28:04 2020 From: bravit111 at gmail.com (Vitaly Bragilevsky) Date: Mon, 10 Feb 2020 11:28:04 +0300 Subject: [ghc-steering-committee] Record dot notation In-Reply-To: References: Message-ID: Hello, While I was leaning towards rejecting, I've changed my mind. Simon's idea that this proposal brings Haskell closer to other programming languages in terms of record selection is quite convincing. I'm next to Iavor finding (4) easier to explain. I agree with Joachim that introducing whitespace-sensitivity can be misleading, especially while explaining this new notation to others. Thus, I prefer: 5 > 4 > 2 > 3 > 1 Vitaly пт, 7 февр. 2020 г. в 20:13, Simon Peyton Jones via ghc-steering-committee < ghc-steering-committee at haskell.org>: > 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 > -------------- next part -------------- An HTML attachment was scrubbed... URL: From marlowsd at gmail.com Mon Feb 10 09:58:06 2020 From: marlowsd at gmail.com (Simon Marlow) Date: Mon, 10 Feb 2020 09:58:06 +0000 Subject: [ghc-steering-committee] Record dot notation In-Reply-To: References: Message-ID: On Fri, 7 Feb 2020 at 22:37, Joachim Breitner wrote: > > I really would prefer a design where all these questions do not even > need to be asked… > Me too. Also what about (.x) vs. ( .x), are those the same? > 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.) > [...] > 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. > I'm also against whitespace-sensitivity and I lean towards this ordering too. But I'm going with: 5 > 2 > 1 > 4 > 3 Rationale: (5) seems the easiest to explain and has the fewest special cases, yet covers the use-cases we're interested in. Beyond that I want to be conservative because I find it hard to predict the ramifications of the more-complex alternatives 4/3, so I've put 2/1 ahead of those. I've made my peace with the current record selection syntax binding more tightly than application, and indeed I often rely on it to avoid a $, so I'm OK with 4 over 3. Cheers Simon > > > 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/ > > > _______________________________________________ > 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: From rae at richarde.dev Mon Feb 10 12:14:20 2020 From: rae at richarde.dev (Richard Eisenberg) Date: Mon, 10 Feb 2020 12:14:20 +0000 Subject: [ghc-steering-committee] Record dot notation In-Reply-To: References: Message-ID: Upon careful consideration, I think the whitespace concerns here are somewhat ill-founded. First, please see https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0229-whitespace-bang-patterns.rst#proposed-change-specification , where (among other points), a careful description of "loose infix" vs "prefix" vs "suffix" vs "tight infix" is discussed. Here is a set of examples: a ! b -- a loose infix occurrence a!b -- a tight infix occurrence a !b -- a prefix occurrence a! b -- a suffix occurrence This distinction is *not* just made by example, but that proposal (which has been accepted) defines these precisely. So, the comments on this thread about what counts as a naked selector are addressed: a naked selector is one where the dot is a prefix occurrence. Other whitespace-wariness comes from worrying about the distinction between prefix and tight infix occurrences. That is, should we differentiate between the interpretation of `f r.x` and `f r .x`. Yet in all versions of any of this, we differentiate between loose infix and the others. Thus there is *always* whitespace-sensitivity around dot. Note that this is true, as Simon PJ pointed out, regardless of this proposal, where a tight-infix usage of a dot with a capitalized identifier on the left is taken as a module qualification. In all of its versions, this proposal *increases* the whitespace sensitivity, by further distinguishing between prefix occurrences of dot and other usages. Let's compare options 3 and 5 with this analysis then: Option 3: loose-infix: whatever (.) is in scope tight-infix: - if left-hand is a capitalized identifier: module qualification - otherwise: record selection, binding tighter than function application prefix: postfix record selection, binding like function application suffix: presumably, whatever (.) is in scope Option 5: loose-infix: whatever (.) is in scope tight-infix: - if left-hand is a capitalized identifier: module qualification - otherwise: postfix record selection, binding like function application prefix: postfix record selection, binding like function application suffix: presumably, whatever (.) is in scope My point here is that option (5) is no more or less whitespace sensitive than option (3). Both need the same cases to figure what the period character in your code means. I think this is why Simon PJ has keyed this part of the debate to module qualification: that existing feature (not under debate) essentially breaks the symmetry here, meaning that we have more room to work with without breaking symmetry further. My vote is thus: 3 > 5 > 2 > 4 > 1 Other points of motivation: - Despite my argument above, I see the merit in (5). I just think that an argument "we don't want dot to be whitespace-sensitive" isn't really effective. - I want to accept this proposal. We're not going to get another go at this. - I really don't like the way record-update binds, and (4) reminds me too much of that. Richard > On Feb 10, 2020, at 9:58 AM, Simon Marlow wrote: > > On Fri, 7 Feb 2020 at 22:37, Joachim Breitner > wrote: > > I really would prefer a design where all these questions do not even > need to be asked… > > Me too. Also what about (.x) vs. ( .x), are those the same? > > 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.) > > [...] > > 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. > > I'm also against whitespace-sensitivity and I lean towards this ordering too. > But I'm going with: > > 5 > 2 > 1 > 4 > 3 > > Rationale: (5) seems the easiest to explain and has the fewest special cases, yet covers the use-cases we're interested in. Beyond that I want to be conservative because I find it hard to predict the ramifications of the more-complex alternatives 4/3, so I've put 2/1 ahead of those. I've made my peace with the current record selection syntax binding more tightly than application, and indeed I often rely on it to avoid a $, so I'm OK with 4 over 3. > > Cheers > Simon > > > > > 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/ > > > _______________________________________________ > 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 -------------- next part -------------- An HTML attachment was scrubbed... URL: From simonpj at microsoft.com Mon Feb 10 17:19:58 2020 From: simonpj at microsoft.com (Simon Peyton Jones) Date: Mon, 10 Feb 2020 17:19:58 +0000 Subject: [ghc-steering-committee] Record dot notation In-Reply-To: References: Message-ID: My point here is that option (5) is no more or less whitespace sensitive than option (3). Both need the same cases to figure what the period character in your code means. I think this is why Simon PJ has keyed this part of the debate to module qualification: that existing feature (not under debate) essentially breaks the symmetry here, meaning that we have more room to work with without breaking symmetry further. You’ve put it very well. Indeed, we could key it even more tightly to module qualification, by making the lexical rule exactly the same: just as M.x is treated as binding super-tightly, so is r.x. If you like, M.x is a lexeme, and so is r.x. They even have the same connotation (the x component of M or r respectively). What about (f e).y, or f{-blah-}.y? Well, you can’t write qualified modules that way; it becomes two or more lexemes. I’d be perfectly content to do the same for record selections, using Joachim’s rule 5 for every case *except* the case that parses exactly like module qualifiers (modulo upper case vs lower case). TL;DR: I’m arguing that (f r.x) means (f (r.x)) just as (f M.x) means (f (M.x)). But I don’t care about f (blah blah blah).x I’d be quite content with that meaning f (bla blha blah) .x as Joachim suggests. Would that help to resolve this debate? I had not thought of it in that way before, but Joachim and Richard have helped met to do so, thank you. Simon From: ghc-steering-committee On Behalf Of Richard Eisenberg Sent: 10 February 2020 12:14 To: Simon Marlow Cc: ghc-steering-committee ; Joachim Breitner Subject: Re: [ghc-steering-committee] Record dot notation Upon careful consideration, I think the whitespace concerns here are somewhat ill-founded. First, please see https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0229-whitespace-bang-patterns.rst#proposed-change-specification, where (among other points), a careful description of "loose infix" vs "prefix" vs "suffix" vs "tight infix" is discussed. Here is a set of examples: a ! b -- a loose infix occurrence a!b -- a tight infix occurrence a !b -- a prefix occurrence a! b -- a suffix occurrence This distinction is *not* just made by example, but that proposal (which has been accepted) defines these precisely. So, the comments on this thread about what counts as a naked selector are addressed: a naked selector is one where the dot is a prefix occurrence. Other whitespace-wariness comes from worrying about the distinction between prefix and tight infix occurrences. That is, should we differentiate between the interpretation of `f r.x` and `f r .x`. Yet in all versions of any of this, we differentiate between loose infix and the others. Thus there is *always* whitespace-sensitivity around dot. Note that this is true, as Simon PJ pointed out, regardless of this proposal, where a tight-infix usage of a dot with a capitalized identifier on the left is taken as a module qualification. In all of its versions, this proposal *increases* the whitespace sensitivity, by further distinguishing between prefix occurrences of dot and other usages. Let's compare options 3 and 5 with this analysis then: Option 3: loose-infix: whatever (.) is in scope tight-infix: - if left-hand is a capitalized identifier: module qualification - otherwise: record selection, binding tighter than function application prefix: postfix record selection, binding like function application suffix: presumably, whatever (.) is in scope Option 5: loose-infix: whatever (.) is in scope tight-infix: - if left-hand is a capitalized identifier: module qualification - otherwise: postfix record selection, binding like function application prefix: postfix record selection, binding like function application suffix: presumably, whatever (.) is in scope My point here is that option (5) is no more or less whitespace sensitive than option (3). Both need the same cases to figure what the period character in your code means. I think this is why Simon PJ has keyed this part of the debate to module qualification: that existing feature (not under debate) essentially breaks the symmetry here, meaning that we have more room to work with without breaking symmetry further. My vote is thus: 3 > 5 > 2 > 4 > 1 Other points of motivation: - Despite my argument above, I see the merit in (5). I just think that an argument "we don't want dot to be whitespace-sensitive" isn't really effective. - I want to accept this proposal. We're not going to get another go at this. - I really don't like the way record-update binds, and (4) reminds me too much of that. Richard On Feb 10, 2020, at 9:58 AM, Simon Marlow > wrote: On Fri, 7 Feb 2020 at 22:37, Joachim Breitner > wrote: I really would prefer a design where all these questions do not even need to be asked… Me too. Also what about (.x) vs. ( .x), are those the same? 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.) [...] 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. I'm also against whitespace-sensitivity and I lean towards this ordering too. But I'm going with: 5 > 2 > 1 > 4 > 3 Rationale: (5) seems the easiest to explain and has the fewest special cases, yet covers the use-cases we're interested in. Beyond that I want to be conservative because I find it hard to predict the ramifications of the more-complex alternatives 4/3, so I've put 2/1 ahead of those. I've made my peace with the current record selection syntax binding more tightly than application, and indeed I often rely on it to avoid a $, so I'm OK with 4 over 3. Cheers Simon 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/ _______________________________________________ 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 -------------- next part -------------- An HTML attachment was scrubbed... URL: From iavor.diatchki at gmail.com Mon Feb 10 18:55:09 2020 From: iavor.diatchki at gmail.com (Iavor Diatchki) Date: Mon, 10 Feb 2020 10:55:09 -0800 Subject: [ghc-steering-committee] Record dot notation In-Reply-To: References: Message-ID: I think the nice thing about 4 and 5 is that we can say that `.x` is just a new token---a record selector---much like `M.x` is a token is its own right (the `.` there is not really an "infix" operator). We don't need any discussion of the "looseness" of operators, etc. The difference between 4 and 5 is what happens when there are 3 tokens in a row like this: x y .z -- identifier, identifier, selector with 4 (the OCaml way) we have that this means: x (y.z) with 5 (the JS way?) we have that this means: (x y) .z I still think that 4 makes the most sense for Haskell because, I would like `f x .y` and `f x.y` to both mean `f (x.y)`. The fact that selection has higher precedence than application also matches the design choice we've already made that record update has higher precedence too, so it matches `f x { y = True }` . Having thought a bit more about it, I'd update my vote to also include 5: 4 > 5 > 2 > 1 > 3 (i.e., I like the token based approach, and favor "OCaml" style over "JS" style). -Iavor On Mon, Feb 10, 2020 at 9:20 AM Simon Peyton Jones via ghc-steering-committee wrote: > My point here is that option (5) is no more or less whitespace sensitive > than option (3). Both need the same cases to figure what the period > character in your code means. I think this is why Simon PJ has keyed this > part of the debate to module qualification: that existing feature (not > under debate) essentially breaks the symmetry here, meaning that we have > more room to work with without breaking symmetry further. > > > > You’ve put it very well. Indeed, we could key it even more tightly to > module qualification, by making the lexical rule exactly the same: just as > M.x is treated as binding super-tightly, so is r.x. If you like, M.x is a > lexeme, and so is r.x. They even have the same connotation (the x > component of M or r respectively). > > > > What about (f e).y, or f{-blah-}.y? Well, you can’t write qualified > modules that way; it becomes two or more lexemes. I’d be perfectly content > to do the same for record selections, using Joachim’s rule 5 for every case > **except** the case that parses exactly like module qualifiers (modulo > upper case vs lower case). > > > > TL;DR: I’m arguing that (f r.x) means (f (r.x)) just as (f M.x) means (f > (M.x)). > > > > But I don’t care about > > f (blah blah blah).x > > I’d be quite content with that meaning > > f (bla blha blah) .x > > as Joachim suggests. > > > > Would that help to resolve this debate? I had not thought of it in that > way before, but Joachim and Richard have helped met to do so, thank you. > > > > Simon > > > > *From:* ghc-steering-committee > *On Behalf Of *Richard Eisenberg > *Sent:* 10 February 2020 12:14 > *To:* Simon Marlow > *Cc:* ghc-steering-committee ; > Joachim Breitner > *Subject:* Re: [ghc-steering-committee] Record dot notation > > > > Upon careful consideration, I think the whitespace concerns here are > somewhat ill-founded. > > > > First, please see > https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0229-whitespace-bang-patterns.rst#proposed-change-specification, > where (among other points), a careful description of "loose infix" vs > "prefix" vs "suffix" vs "tight infix" is discussed. Here is a set of > examples: > > a ! b -- a loose infix occurrence > > a!b -- a tight infix occurrence > > a !b -- a prefix occurrence > > a! b -- a suffix occurrence > > This distinction is *not* just made by example, but that proposal (which > has been accepted) defines these precisely. So, the comments on this thread > about what counts as a naked selector are addressed: a naked selector is > one where the dot is a prefix occurrence. > > > > Other whitespace-wariness comes from worrying about the distinction > between prefix and tight infix occurrences. That is, should we > differentiate between the interpretation of `f r.x` and `f r .x`. Yet in > all versions of any of this, we differentiate between loose infix and the > others. Thus there is *always* whitespace-sensitivity around dot. Note that > this is true, as Simon PJ pointed out, regardless of this proposal, where a > tight-infix usage of a dot with a capitalized identifier on the left is > taken as a module qualification. In all of its versions, this proposal > *increases* the whitespace sensitivity, by further distinguishing between > prefix occurrences of dot and other usages. > > > > Let's compare options 3 and 5 with this analysis then: > > > > Option 3: > > loose-infix: whatever (.) is in scope > > tight-infix: > > - if left-hand is a capitalized identifier: module qualification > > - otherwise: record selection, binding tighter than function application > > prefix: postfix record selection, binding like function application > > suffix: presumably, whatever (.) is in scope > > > > Option 5: > > loose-infix: whatever (.) is in scope > > tight-infix: > > - if left-hand is a capitalized identifier: module qualification > > - otherwise: postfix record selection, binding like function application > > prefix: postfix record selection, binding like function application > > suffix: presumably, whatever (.) is in scope > > > > My point here is that option (5) is no more or less whitespace sensitive > than option (3). Both need the same cases to figure what the period > character in your code means. I think this is why Simon PJ has keyed this > part of the debate to module qualification: that existing feature (not > under debate) essentially breaks the symmetry here, meaning that we have > more room to work with without breaking symmetry further. > > > > My vote is thus: > > > > 3 > 5 > 2 > 4 > 1 > > > > Other points of motivation: > > - Despite my argument above, I see the merit in (5). I just think that an > argument "we don't want dot to be whitespace-sensitive" isn't really > effective. > > - I want to accept this proposal. We're not going to get another go at > this. > > - I really don't like the way record-update binds, and (4) reminds me too > much of that. > > > > Richard > > > > On Feb 10, 2020, at 9:58 AM, Simon Marlow wrote: > > > > On Fri, 7 Feb 2020 at 22:37, Joachim Breitner > wrote: > > > I really would prefer a design where all these questions do not even > need to be asked… > > > > Me too. Also what about (.x) vs. ( .x), are those the same? > > > > 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.) > > > > [...] > > > > 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. > > > > I'm also against whitespace-sensitivity and I lean towards this ordering > too. > > But I'm going with: > > > > 5 > 2 > 1 > 4 > 3 > > > > Rationale: (5) seems the easiest to explain and has the fewest special > cases, yet covers the use-cases we're interested in. Beyond that I want to > be conservative because I find it hard to predict the ramifications of the > more-complex alternatives 4/3, so I've put 2/1 ahead of those. I've made my > peace with the current record selection syntax binding more tightly than > application, and indeed I often rely on it to avoid a $, so I'm OK with 4 > over 3. > > > > Cheers > > Simon > > > > > > > > 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/ > > > _______________________________________________ > 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 > > > _______________________________________________ > 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: From cgibbard at gmail.com Mon Feb 10 19:07:18 2020 From: cgibbard at gmail.com (Cale Gibbard) Date: Mon, 10 Feb 2020 14:07:18 -0500 Subject: [ghc-steering-committee] Record dot notation In-Reply-To: References: Message-ID: This is sort of offtopic for the thread, but I thought I'd mention it anyway, lately I've been thinking that my ideal design for record field selectors would involve promoted GADTs, used to describe the universe of fields that a record was comprised from. That is, the 'k' in HasField (x :: k) r a becomes f a, for some GADT f, whose indices describe the types of the potential fields which might be had by a variety of records. There's nothing preventing this at present apart from the need to have promoted GADTs, but I'm not sure how it would fit in at all with this syntax (especially as "field names" potentially become more complicated terms with actual structure to them rather than simply strings). On Mon, 10 Feb 2020 at 13:55, Iavor Diatchki wrote: > > I think the nice thing about 4 and 5 is that we can say that `.x` is just a new token---a record selector---much like `M.x` is a token is its own right (the `.` there is not really an "infix" operator). We don't need any discussion of the "looseness" of operators, etc. > The difference between 4 and 5 is what happens when there are 3 tokens in a row like this: > > x y .z -- identifier, identifier, selector > > with 4 (the OCaml way) we have that this means: x (y.z) > with 5 (the JS way?) we have that this means: (x y) .z > > I still think that 4 makes the most sense for Haskell because, I would like `f x .y` and `f x.y` to both mean `f (x.y)`. The fact that selection has higher precedence than application also matches the design choice we've already made that record update has higher precedence too, so it matches `f x { y = True }` . > > Having thought a bit more about it, I'd update my vote to also include 5: > > 4 > 5 > 2 > 1 > 3 > > (i.e., I like the token based approach, and favor "OCaml" style over "JS" style). > > -Iavor > > > > > > > > On Mon, Feb 10, 2020 at 9:20 AM Simon Peyton Jones via ghc-steering-committee wrote: >> >> My point here is that option (5) is no more or less whitespace sensitive than option (3). Both need the same cases to figure what the period character in your code means. I think this is why Simon PJ has keyed this part of the debate to module qualification: that existing feature (not under debate) essentially breaks the symmetry here, meaning that we have more room to work with without breaking symmetry further. >> >> >> >> You’ve put it very well. Indeed, we could key it even more tightly to module qualification, by making the lexical rule exactly the same: just as M.x is treated as binding super-tightly, so is r.x. If you like, M.x is a lexeme, and so is r.x. They even have the same connotation (the x component of M or r respectively). >> >> >> >> What about (f e).y, or f{-blah-}.y? Well, you can’t write qualified modules that way; it becomes two or more lexemes. I’d be perfectly content to do the same for record selections, using Joachim’s rule 5 for every case *except* the case that parses exactly like module qualifiers (modulo upper case vs lower case). >> >> >> >> TL;DR: I’m arguing that (f r.x) means (f (r.x)) just as (f M.x) means (f (M.x)). >> >> >> >> But I don’t care about >> >> f (blah blah blah).x >> >> I’d be quite content with that meaning >> >> f (bla blha blah) .x >> >> as Joachim suggests. >> >> >> >> Would that help to resolve this debate? I had not thought of it in that way before, but Joachim and Richard have helped met to do so, thank you. >> >> >> >> Simon >> >> >> >> From: ghc-steering-committee On Behalf Of Richard Eisenberg >> Sent: 10 February 2020 12:14 >> To: Simon Marlow >> Cc: ghc-steering-committee ; Joachim Breitner >> Subject: Re: [ghc-steering-committee] Record dot notation >> >> >> >> Upon careful consideration, I think the whitespace concerns here are somewhat ill-founded. >> >> >> >> First, please see https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0229-whitespace-bang-patterns.rst#proposed-change-specification, where (among other points), a careful description of "loose infix" vs "prefix" vs "suffix" vs "tight infix" is discussed. Here is a set of examples: >> >> a ! b -- a loose infix occurrence >> >> a!b -- a tight infix occurrence >> >> a !b -- a prefix occurrence >> >> a! b -- a suffix occurrence >> >> This distinction is *not* just made by example, but that proposal (which has been accepted) defines these precisely. So, the comments on this thread about what counts as a naked selector are addressed: a naked selector is one where the dot is a prefix occurrence. >> >> >> >> Other whitespace-wariness comes from worrying about the distinction between prefix and tight infix occurrences. That is, should we differentiate between the interpretation of `f r.x` and `f r .x`. Yet in all versions of any of this, we differentiate between loose infix and the others. Thus there is *always* whitespace-sensitivity around dot. Note that this is true, as Simon PJ pointed out, regardless of this proposal, where a tight-infix usage of a dot with a capitalized identifier on the left is taken as a module qualification. In all of its versions, this proposal *increases* the whitespace sensitivity, by further distinguishing between prefix occurrences of dot and other usages. >> >> >> >> Let's compare options 3 and 5 with this analysis then: >> >> >> >> Option 3: >> >> loose-infix: whatever (.) is in scope >> >> tight-infix: >> >> - if left-hand is a capitalized identifier: module qualification >> >> - otherwise: record selection, binding tighter than function application >> >> prefix: postfix record selection, binding like function application >> >> suffix: presumably, whatever (.) is in scope >> >> >> >> Option 5: >> >> loose-infix: whatever (.) is in scope >> >> tight-infix: >> >> - if left-hand is a capitalized identifier: module qualification >> >> - otherwise: postfix record selection, binding like function application >> >> prefix: postfix record selection, binding like function application >> >> suffix: presumably, whatever (.) is in scope >> >> >> >> My point here is that option (5) is no more or less whitespace sensitive than option (3). Both need the same cases to figure what the period character in your code means. I think this is why Simon PJ has keyed this part of the debate to module qualification: that existing feature (not under debate) essentially breaks the symmetry here, meaning that we have more room to work with without breaking symmetry further. >> >> >> >> My vote is thus: >> >> >> >> 3 > 5 > 2 > 4 > 1 >> >> >> >> Other points of motivation: >> >> - Despite my argument above, I see the merit in (5). I just think that an argument "we don't want dot to be whitespace-sensitive" isn't really effective. >> >> - I want to accept this proposal. We're not going to get another go at this. >> >> - I really don't like the way record-update binds, and (4) reminds me too much of that. >> >> >> >> Richard >> >> >> >> On Feb 10, 2020, at 9:58 AM, Simon Marlow wrote: >> >> >> >> On Fri, 7 Feb 2020 at 22:37, Joachim Breitner wrote: >> >> >> I really would prefer a design where all these questions do not even >> need to be asked… >> >> >> >> Me too. Also what about (.x) vs. ( .x), are those the same? >> >> >> >> 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.) >> >> >> >> [...] >> >> >> >> 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. >> >> >> >> I'm also against whitespace-sensitivity and I lean towards this ordering too. >> >> But I'm going with: >> >> >> >> 5 > 2 > 1 > 4 > 3 >> >> >> >> Rationale: (5) seems the easiest to explain and has the fewest special cases, yet covers the use-cases we're interested in. Beyond that I want to be conservative because I find it hard to predict the ramifications of the more-complex alternatives 4/3, so I've put 2/1 ahead of those. I've made my peace with the current record selection syntax binding more tightly than application, and indeed I often rely on it to avoid a $, so I'm OK with 4 over 3. >> >> >> >> Cheers >> >> Simon >> >> >> >> >> >> >> >> 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/ >> >> >> _______________________________________________ >> 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 >> >> >> >> _______________________________________________ >> 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 From arnaud.spiwack at tweag.io Tue Feb 11 07:59:15 2020 From: arnaud.spiwack at tweag.io (Spiwack, Arnaud) Date: Tue, 11 Feb 2020 08:59:15 +0100 Subject: [ghc-steering-committee] Record dot notation In-Reply-To: References: Message-ID: 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 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 > -------------- next part -------------- An HTML attachment was scrubbed... URL: From simonpj at microsoft.com Tue Feb 11 10:33:28 2020 From: simonpj at microsoft.com (Simon Peyton Jones) Date: Tue, 11 Feb 2020 10:33:28 +0000 Subject: [ghc-steering-committee] Record dot notation In-Reply-To: References: Message-ID: 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 Sent: 11 February 2020 07:59 To: Simon Peyton Jones 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 > 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 -------------- next part -------------- An HTML attachment was scrubbed... URL: From cgibbard at gmail.com Tue Feb 11 17:28:31 2020 From: cgibbard at gmail.com (Cale Gibbard) Date: Tue, 11 Feb 2020 12:28:31 -0500 Subject: [ghc-steering-committee] Record dot notation In-Reply-To: References: Message-ID: 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 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 > Sent: 11 February 2020 07:59 > To: Simon Peyton Jones > 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 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 From marlowsd at gmail.com Wed Feb 12 11:21:17 2020 From: marlowsd at gmail.com (Simon Marlow) Date: Wed, 12 Feb 2020 11:21:17 +0000 Subject: [ghc-steering-committee] Record dot notation In-Reply-To: References: Message-ID: On Mon, 10 Feb 2020 at 14:15, Richard Eisenberg wrote: > Upon careful consideration, I think the whitespace concerns here are > somewhat ill-founded. > > First, please see > https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0229-whitespace-bang-patterns.rst#proposed-change-specification, > where (among other points), a careful description of "loose infix" vs > "prefix" vs "suffix" vs "tight infix" is discussed. Here is a set of > examples: > > a ! b -- a loose infix occurrence > a!b -- a tight infix occurrence > a !b -- a prefix occurrence > a! b -- a suffix occurrence > > Yes and I was not very keen on that proposal (my concerns are on the discussion thread). > This distinction is *not* just made by example, but that proposal (which > has been accepted) defines these precisely. So, the comments on this thread > about what counts as a naked selector are addressed: a naked selector is > one where the dot is a prefix occurrence. > > Other whitespace-wariness comes from worrying about the distinction > between prefix and tight infix occurrences. That is, should we > differentiate between the interpretation of `f r.x` and `f r .x`. Yet in > all versions of any of this, we differentiate between loose infix and the > others. Thus there is *always* whitespace-sensitivity around dot. Note that > this is true, as Simon PJ pointed out, regardless of this proposal, where a > tight-infix usage of a dot with a capitalized identifier on the left is > taken as a module qualification. In all of its versions, this proposal > *increases* the whitespace sensitivity, by further distinguishing between > prefix occurrences of dot and other usages. > > Let's compare options 3 and 5 with this analysis then: > > Option 3: > loose-infix: whatever (.) is in scope > tight-infix: > - if left-hand is a capitalized identifier: module qualification > - otherwise: record selection, binding tighter than function application > prefix: postfix record selection, binding like function application > suffix: presumably, whatever (.) is in scope > > Option 5: > loose-infix: whatever (.) is in scope > tight-infix: > - if left-hand is a capitalized identifier: module qualification > - otherwise: postfix record selection, binding like function application > prefix: postfix record selection, binding like function application > suffix: presumably, whatever (.) is in scope > That's a good summary - but note that under Option 5 tight-infix and prefix are the same, modulo the qualified-identifier case, and this is the key difference. What I wanted to avoid was having to use the language of tight-infix vs. prefix AT ALL in understanding how record selection syntax works, and (5) achieves that whereas (3) doesn't. Under option 5 we get one new lexeme: . and everything else can be handled at the context-free grammar level. This is a nice minimal addition to the language. We don't have to invoke the mess that is proposal #229, which was forced upon us because BangPatterns and TypeApplications made the handling of (!) and (@) so complicated. If we don't have to do the same to (.), I believe we should take the opportunity to avoid it. Cheers Simon > > My point here is that option (5) is no more or less whitespace sensitive > than option (3). Both need the same cases to figure what the period > character in your code means. I think this is why Simon PJ has keyed this > part of the debate to module qualification: that existing feature (not > under debate) essentially breaks the symmetry here, meaning that we have > more room to work with without breaking symmetry further. > > My vote is thus: > > 3 > 5 > 2 > 4 > 1 > > Other points of motivation: > - Despite my argument above, I see the merit in (5). I just think that an > argument "we don't want dot to be whitespace-sensitive" isn't really > effective. > - I want to accept this proposal. We're not going to get another go at > this. > - I really don't like the way record-update binds, and (4) reminds me too > much of that. > > Richard > > On Feb 10, 2020, at 9:58 AM, Simon Marlow wrote: > > On Fri, 7 Feb 2020 at 22:37, Joachim Breitner > wrote: > >> >> I really would prefer a design where all these questions do not even >> need to be asked… >> > > Me too. Also what about (.x) vs. ( .x), are those the same? > > >> 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.) >> > > [...] > > >> 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. >> > > I'm also against whitespace-sensitivity and I lean towards this ordering > too. > But I'm going with: > > 5 > 2 > 1 > 4 > 3 > > Rationale: (5) seems the easiest to explain and has the fewest special > cases, yet covers the use-cases we're interested in. Beyond that I want to > be conservative because I find it hard to predict the ramifications of the > more-complex alternatives 4/3, so I've put 2/1 ahead of those. I've made my > peace with the current record selection syntax binding more tightly than > application, and indeed I often rely on it to avoid a $, so I'm OK with 4 > over 3. > > Cheers > Simon > > > >> >> >> 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/ >> >> >> _______________________________________________ >> 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 > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From simonpj at microsoft.com Wed Feb 12 14:53:45 2020 From: simonpj at microsoft.com (Simon Peyton Jones) Date: Wed, 12 Feb 2020 14:53:45 +0000 Subject: [ghc-steering-committee] Record dot notation In-Reply-To: References: Message-ID: Don’t forget option (6): like (5) but treat r.x as a lexeme. I find it hard to justify a language in which f M.x means f (M.x) but f m.x means (f m).x especially when the “.” means, in both cases, “take the x component of the thing on the left”. So here I’m leaning even harder on the connection with qualified names: let’s simply be consistent with that. I’m quite content to follow (5) on the meaning of f (g 3).x That is, it means the same as (f (g 3) .x), namely (f (g 3)).x But I’m very keen on maintaining consistency with qualified names when the thing on the LHS is a token (or dotted chain thereof.) Does anyone else have an alternative beyond 1-6 that they want to put forward? Simon From: ghc-steering-committee On Behalf Of Simon Marlow Sent: 12 February 2020 11:21 To: Richard Eisenberg Cc: ghc-steering-committee ; Joachim Breitner Subject: Re: [ghc-steering-committee] Record dot notation On Mon, 10 Feb 2020 at 14:15, Richard Eisenberg > wrote: Upon careful consideration, I think the whitespace concerns here are somewhat ill-founded. First, please see https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0229-whitespace-bang-patterns.rst#proposed-change-specification, where (among other points), a careful description of "loose infix" vs "prefix" vs "suffix" vs "tight infix" is discussed. Here is a set of examples: a ! b -- a loose infix occurrence a!b -- a tight infix occurrence a !b -- a prefix occurrence a! b -- a suffix occurrence Yes and I was not very keen on that proposal (my concerns are on the discussion thread). This distinction is *not* just made by example, but that proposal (which has been accepted) defines these precisely. So, the comments on this thread about what counts as a naked selector are addressed: a naked selector is one where the dot is a prefix occurrence. Other whitespace-wariness comes from worrying about the distinction between prefix and tight infix occurrences. That is, should we differentiate between the interpretation of `f r.x` and `f r .x`. Yet in all versions of any of this, we differentiate between loose infix and the others. Thus there is *always* whitespace-sensitivity around dot. Note that this is true, as Simon PJ pointed out, regardless of this proposal, where a tight-infix usage of a dot with a capitalized identifier on the left is taken as a module qualification. In all of its versions, this proposal *increases* the whitespace sensitivity, by further distinguishing between prefix occurrences of dot and other usages. Let's compare options 3 and 5 with this analysis then: Option 3: loose-infix: whatever (.) is in scope tight-infix: - if left-hand is a capitalized identifier: module qualification - otherwise: record selection, binding tighter than function application prefix: postfix record selection, binding like function application suffix: presumably, whatever (.) is in scope Option 5: loose-infix: whatever (.) is in scope tight-infix: - if left-hand is a capitalized identifier: module qualification - otherwise: postfix record selection, binding like function application prefix: postfix record selection, binding like function application suffix: presumably, whatever (.) is in scope That's a good summary - but note that under Option 5 tight-infix and prefix are the same, modulo the qualified-identifier case, and this is the key difference. What I wanted to avoid was having to use the language of tight-infix vs. prefix AT ALL in understanding how record selection syntax works, and (5) achieves that whereas (3) doesn't. Under option 5 we get one new lexeme: . and everything else can be handled at the context-free grammar level. This is a nice minimal addition to the language. We don't have to invoke the mess that is proposal #229, which was forced upon us because BangPatterns and TypeApplications made the handling of (!) and (@) so complicated. If we don't have to do the same to (.), I believe we should take the opportunity to avoid it. Cheers Simon My point here is that option (5) is no more or less whitespace sensitive than option (3). Both need the same cases to figure what the period character in your code means. I think this is why Simon PJ has keyed this part of the debate to module qualification: that existing feature (not under debate) essentially breaks the symmetry here, meaning that we have more room to work with without breaking symmetry further. My vote is thus: 3 > 5 > 2 > 4 > 1 Other points of motivation: - Despite my argument above, I see the merit in (5). I just think that an argument "we don't want dot to be whitespace-sensitive" isn't really effective. - I want to accept this proposal. We're not going to get another go at this. - I really don't like the way record-update binds, and (4) reminds me too much of that. Richard On Feb 10, 2020, at 9:58 AM, Simon Marlow > wrote: On Fri, 7 Feb 2020 at 22:37, Joachim Breitner > wrote: I really would prefer a design where all these questions do not even need to be asked… Me too. Also what about (.x) vs. ( .x), are those the same? 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.) [...] 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. I'm also against whitespace-sensitivity and I lean towards this ordering too. But I'm going with: 5 > 2 > 1 > 4 > 3 Rationale: (5) seems the easiest to explain and has the fewest special cases, yet covers the use-cases we're interested in. Beyond that I want to be conservative because I find it hard to predict the ramifications of the more-complex alternatives 4/3, so I've put 2/1 ahead of those. I've made my peace with the current record selection syntax binding more tightly than application, and indeed I often rely on it to avoid a $, so I'm OK with 4 over 3. Cheers Simon 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/ _______________________________________________ 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 -------------- next part -------------- An HTML attachment was scrubbed... URL: From cma at bitemyapp.com Wed Feb 12 15:44:00 2020 From: cma at bitemyapp.com (Christopher Allen) Date: Wed, 12 Feb 2020 09:44:00 -0600 Subject: [ghc-steering-committee] Record dot notation In-Reply-To: References: Message-ID: <33FDA81E-92CB-4D97-88DB-3EB0676EC5B7@bitemyapp.com> Having used OCaml and PureScript, the latter in multiple production projects, I can only vigorously agree with Cale here. > On Feb 11, 2020, at 11:28 AM, Cale Gibbard wrote: > > 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 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 >> Sent: 11 February 2020 07:59 >> To: Simon Peyton Jones >> 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 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 > _______________________________________________ > ghc-steering-committee mailing list > ghc-steering-committee at haskell.org > https://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-steering-committee From marlowsd at gmail.com Wed Feb 12 16:43:52 2020 From: marlowsd at gmail.com (Simon Marlow) Date: Wed, 12 Feb 2020 16:43:52 +0000 Subject: [ghc-steering-committee] Record dot notation In-Reply-To: References: Message-ID: On Wed, 12 Feb 2020 at 14:53, Simon Peyton Jones wrote: > Don’t forget option (6): like (5) but treat r.x as a lexeme. > > > > I find it hard to justify a language in which > > f M.x means f (M.x) > > but f m.x means (f m).x > > > > especially when the “.” means, in both cases, “take the x component of the > thing on the left”. > > > > So here I’m leaning even harder on the connection with qualified names: > let’s simply be consistent with that. > > > > I’m quite content to follow (5) on the meaning of > > f (g 3).x > > That is, it means the same as (f (g 3) .x), namely (f (g 3)).x > Yes OK, I think that's reasonable. (I hadn't digested your earlier message proposing this properly, but I went back and re-read it just now.) I can imagine explaining that to someone - there's a straightforward lexical syntax, and the context-free grammar is similar to the rules for function application. Joachim what do you think? Cheers Simon > > > But I’m very keen on maintaining consistency with qualified names when the > thing on the LHS is a token (or dotted chain thereof.) > > > > Does anyone else have an alternative beyond 1-6 that they want to put > forward? > > > > Simon > > > > *From:* ghc-steering-committee > *On Behalf Of *Simon Marlow > *Sent:* 12 February 2020 11:21 > *To:* Richard Eisenberg > *Cc:* ghc-steering-committee ; > Joachim Breitner > *Subject:* Re: [ghc-steering-committee] Record dot notation > > > > > > On Mon, 10 Feb 2020 at 14:15, Richard Eisenberg wrote: > > Upon careful consideration, I think the whitespace concerns here are > somewhat ill-founded. > > > > First, please see > https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0229-whitespace-bang-patterns.rst#proposed-change-specification > , > where (among other points), a careful description of "loose infix" vs > "prefix" vs "suffix" vs "tight infix" is discussed. Here is a set of > examples: > > a ! b -- a loose infix occurrence > > a!b -- a tight infix occurrence > > a !b -- a prefix occurrence > > a! b -- a suffix occurrence > > Yes and I was not very keen on that proposal (my concerns are on the > discussion thread). > > > > This distinction is *not* just made by example, but that proposal (which > has been accepted) defines these precisely. So, the comments on this thread > about what counts as a naked selector are addressed: a naked selector is > one where the dot is a prefix occurrence. > > > > Other whitespace-wariness comes from worrying about the distinction > between prefix and tight infix occurrences. That is, should we > differentiate between the interpretation of `f r.x` and `f r .x`. Yet in > all versions of any of this, we differentiate between loose infix and the > others. Thus there is *always* whitespace-sensitivity around dot. Note that > this is true, as Simon PJ pointed out, regardless of this proposal, where a > tight-infix usage of a dot with a capitalized identifier on the left is > taken as a module qualification. In all of its versions, this proposal > *increases* the whitespace sensitivity, by further distinguishing between > prefix occurrences of dot and other usages. > > > > Let's compare options 3 and 5 with this analysis then: > > > > Option 3: > > loose-infix: whatever (.) is in scope > > tight-infix: > > - if left-hand is a capitalized identifier: module qualification > > - otherwise: record selection, binding tighter than function application > > prefix: postfix record selection, binding like function application > > suffix: presumably, whatever (.) is in scope > > > > Option 5: > > loose-infix: whatever (.) is in scope > > tight-infix: > > - if left-hand is a capitalized identifier: module qualification > > - otherwise: postfix record selection, binding like function application > > prefix: postfix record selection, binding like function application > > suffix: presumably, whatever (.) is in scope > > > > That's a good summary - but note that under Option 5 tight-infix and > prefix are the same, modulo the qualified-identifier case, and this is the > key difference. What I wanted to avoid was having to use the language of > tight-infix vs. prefix AT ALL in understanding how record selection syntax > works, and (5) achieves that whereas (3) doesn't. > > > > Under option 5 we get one new lexeme: > > . > > and everything else can be handled at the context-free grammar level. This > is a nice minimal addition to the language. We don't have to invoke the > mess that is proposal #229, which was forced upon us because BangPatterns > and TypeApplications made the handling of (!) and (@) so complicated. If we > don't have to do the same to (.), I believe we should take the opportunity > to avoid it. > > > > Cheers > > Simon > > > > > > My point here is that option (5) is no more or less whitespace sensitive > than option (3). Both need the same cases to figure what the period > character in your code means. I think this is why Simon PJ has keyed this > part of the debate to module qualification: that existing feature (not > under debate) essentially breaks the symmetry here, meaning that we have > more room to work with without breaking symmetry further. > > > > My vote is thus: > > > > 3 > 5 > 2 > 4 > 1 > > > > Other points of motivation: > > - Despite my argument above, I see the merit in (5). I just think that an > argument "we don't want dot to be whitespace-sensitive" isn't really > effective. > > - I want to accept this proposal. We're not going to get another go at > this. > > - I really don't like the way record-update binds, and (4) reminds me too > much of that. > > > > Richard > > > > On Feb 10, 2020, at 9:58 AM, Simon Marlow wrote: > > > > On Fri, 7 Feb 2020 at 22:37, Joachim Breitner > wrote: > > > I really would prefer a design where all these questions do not even > need to be asked… > > > > Me too. Also what about (.x) vs. ( .x), are those the same? > > > > 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.) > > > > [...] > > > > 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. > > > > I'm also against whitespace-sensitivity and I lean towards this ordering > too. > > But I'm going with: > > > > 5 > 2 > 1 > 4 > 3 > > > > Rationale: (5) seems the easiest to explain and has the fewest special > cases, yet covers the use-cases we're interested in. Beyond that I want to > be conservative because I find it hard to predict the ramifications of the > more-complex alternatives 4/3, so I've put 2/1 ahead of those. I've made my > peace with the current record selection syntax binding more tightly than > application, and indeed I often rely on it to avoid a $, so I'm OK with 4 > over 3. > > > > Cheers > > Simon > > > > > > > > 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/ > > > > _______________________________________________ > 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 > > > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From iavor.diatchki at gmail.com Wed Feb 12 17:58:27 2020 From: iavor.diatchki at gmail.com (Iavor Diatchki) Date: Wed, 12 Feb 2020 09:58:27 -0800 Subject: [ghc-steering-committee] Record dot notation In-Reply-To: References: Message-ID: Both option (4) and option (5) require just one new lexeme .X, and the rest can be handled in the parser. The difference between them is the precedence of selection, 4 has higher precedence than application (just like record update), while 5 has the same precedence as application. Most commonly, this would show up in examples like `f x.y`: with (4) this means `f (x.y)` with (5) this means `(f x).y`. Simon PJ, why do we need the special case for option (6), when it seems option (4) does the same thing in a simpler way? I am strongly against the new option (6) because `f x.y` and `f (g x).y` mean very different things, and being able to name and abstract expressions is one of the big selling point of Haskell. Also having a single consistent rule is a lot easier to teach and read, there really is no need for a special case here. -Iavor On Wed, Feb 12, 2020 at 8:44 AM Simon Marlow wrote: > On Wed, 12 Feb 2020 at 14:53, Simon Peyton Jones > wrote: > >> Don’t forget option (6): like (5) but treat r.x as a lexeme. >> >> >> >> I find it hard to justify a language in which >> >> f M.x means f (M.x) >> >> but f m.x means (f m).x >> >> >> >> especially when the “.” means, in both cases, “take the x component of >> the thing on the left”. >> >> >> >> So here I’m leaning even harder on the connection with qualified names: >> let’s simply be consistent with that. >> >> >> >> I’m quite content to follow (5) on the meaning of >> >> f (g 3).x >> >> That is, it means the same as (f (g 3) .x), namely (f (g 3)).x >> > > Yes OK, I think that's reasonable. (I hadn't digested your earlier message > proposing this properly, but I went back and re-read it just now.) > > I can imagine explaining that to someone - there's a straightforward > lexical syntax, and the context-free grammar is similar to the rules for > function application. > > Joachim what do you think? > > Cheers > Simon > > >> >> >> But I’m very keen on maintaining consistency with qualified names when >> the thing on the LHS is a token (or dotted chain thereof.) >> >> >> >> Does anyone else have an alternative beyond 1-6 that they want to put >> forward? >> >> >> >> Simon >> >> >> >> *From:* ghc-steering-committee < >> ghc-steering-committee-bounces at haskell.org> *On Behalf Of *Simon Marlow >> *Sent:* 12 February 2020 11:21 >> *To:* Richard Eisenberg >> *Cc:* ghc-steering-committee ; >> Joachim Breitner >> *Subject:* Re: [ghc-steering-committee] Record dot notation >> >> >> >> >> >> On Mon, 10 Feb 2020 at 14:15, Richard Eisenberg wrote: >> >> Upon careful consideration, I think the whitespace concerns here are >> somewhat ill-founded. >> >> >> >> First, please see >> https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0229-whitespace-bang-patterns.rst#proposed-change-specification >> , >> where (among other points), a careful description of "loose infix" vs >> "prefix" vs "suffix" vs "tight infix" is discussed. Here is a set of >> examples: >> >> a ! b -- a loose infix occurrence >> >> a!b -- a tight infix occurrence >> >> a !b -- a prefix occurrence >> >> a! b -- a suffix occurrence >> >> Yes and I was not very keen on that proposal (my concerns are on the >> discussion thread). >> >> >> >> This distinction is *not* just made by example, but that proposal (which >> has been accepted) defines these precisely. So, the comments on this thread >> about what counts as a naked selector are addressed: a naked selector is >> one where the dot is a prefix occurrence. >> >> >> >> Other whitespace-wariness comes from worrying about the distinction >> between prefix and tight infix occurrences. That is, should we >> differentiate between the interpretation of `f r.x` and `f r .x`. Yet in >> all versions of any of this, we differentiate between loose infix and the >> others. Thus there is *always* whitespace-sensitivity around dot. Note that >> this is true, as Simon PJ pointed out, regardless of this proposal, where a >> tight-infix usage of a dot with a capitalized identifier on the left is >> taken as a module qualification. In all of its versions, this proposal >> *increases* the whitespace sensitivity, by further distinguishing between >> prefix occurrences of dot and other usages. >> >> >> >> Let's compare options 3 and 5 with this analysis then: >> >> >> >> Option 3: >> >> loose-infix: whatever (.) is in scope >> >> tight-infix: >> >> - if left-hand is a capitalized identifier: module qualification >> >> - otherwise: record selection, binding tighter than function application >> >> prefix: postfix record selection, binding like function application >> >> suffix: presumably, whatever (.) is in scope >> >> >> >> Option 5: >> >> loose-infix: whatever (.) is in scope >> >> tight-infix: >> >> - if left-hand is a capitalized identifier: module qualification >> >> - otherwise: postfix record selection, binding like function application >> >> prefix: postfix record selection, binding like function application >> >> suffix: presumably, whatever (.) is in scope >> >> >> >> That's a good summary - but note that under Option 5 tight-infix and >> prefix are the same, modulo the qualified-identifier case, and this is the >> key difference. What I wanted to avoid was having to use the language of >> tight-infix vs. prefix AT ALL in understanding how record selection syntax >> works, and (5) achieves that whereas (3) doesn't. >> >> >> >> Under option 5 we get one new lexeme: >> >> . >> >> and everything else can be handled at the context-free grammar level. >> This is a nice minimal addition to the language. We don't have to invoke >> the mess that is proposal #229, which was forced upon us because >> BangPatterns and TypeApplications made the handling of (!) and (@) so >> complicated. If we don't have to do the same to (.), I believe we should >> take the opportunity to avoid it. >> >> >> >> Cheers >> >> Simon >> >> >> >> >> >> My point here is that option (5) is no more or less whitespace sensitive >> than option (3). Both need the same cases to figure what the period >> character in your code means. I think this is why Simon PJ has keyed this >> part of the debate to module qualification: that existing feature (not >> under debate) essentially breaks the symmetry here, meaning that we have >> more room to work with without breaking symmetry further. >> >> >> >> My vote is thus: >> >> >> >> 3 > 5 > 2 > 4 > 1 >> >> >> >> Other points of motivation: >> >> - Despite my argument above, I see the merit in (5). I just think that an >> argument "we don't want dot to be whitespace-sensitive" isn't really >> effective. >> >> - I want to accept this proposal. We're not going to get another go at >> this. >> >> - I really don't like the way record-update binds, and (4) reminds me too >> much of that. >> >> >> >> Richard >> >> >> >> On Feb 10, 2020, at 9:58 AM, Simon Marlow wrote: >> >> >> >> On Fri, 7 Feb 2020 at 22:37, Joachim Breitner >> wrote: >> >> >> I really would prefer a design where all these questions do not even >> need to be asked… >> >> >> >> Me too. Also what about (.x) vs. ( .x), are those the same? >> >> >> >> 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.) >> >> >> >> [...] >> >> >> >> 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. >> >> >> >> I'm also against whitespace-sensitivity and I lean towards this ordering >> too. >> >> But I'm going with: >> >> >> >> 5 > 2 > 1 > 4 > 3 >> >> >> >> Rationale: (5) seems the easiest to explain and has the fewest special >> cases, yet covers the use-cases we're interested in. Beyond that I want to >> be conservative because I find it hard to predict the ramifications of the >> more-complex alternatives 4/3, so I've put 2/1 ahead of those. I've made my >> peace with the current record selection syntax binding more tightly than >> application, and indeed I often rely on it to avoid a $, so I'm OK with 4 >> over 3. >> >> >> >> Cheers >> >> Simon >> >> >> >> >> >> >> >> 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/ >> >> >> >> _______________________________________________ >> 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 >> >> >> >> >> _______________________________________________ > 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: From mail at joachim-breitner.de Wed Feb 12 18:18:40 2020 From: mail at joachim-breitner.de (Joachim Breitner) Date: Wed, 12 Feb 2020 10:18:40 -0800 Subject: [ghc-steering-committee] Record dot notation In-Reply-To: References: Message-ID: <308baabd75d109208f5fdd7d85d74a79ade3247a.camel@joachim-breitner.de> Hi, Am Mittwoch, den 12.02.2020, 16:43 +0000 schrieb Simon Marlow: > Joachim what do you think? what Iavor said; although I could maybe warm up to still ranking 6 > 1 as a compromise trying to please the largest number of people. I also think that the more fundamental (and therefore much more relevant) issues that Cale raises deserve more attention. Cheers, Joachim -- Joachim Breitner mail at joachim-breitner.de http://www.joachim-breitner.de/ From simonpj at microsoft.com Wed Feb 12 20:04:55 2020 From: simonpj at microsoft.com (Simon Peyton Jones) Date: Wed, 12 Feb 2020 20:04:55 +0000 Subject: [ghc-steering-committee] Record dot notation In-Reply-To: References: Message-ID: Simon PJ, why do we need the special case for option (6), when it seems option (4) does the same thing in a simpler way? Because I very much dislike breaking the “space is function application, and binds to the left” rule. No more, nor less, than that. I regret the Haskell committee’s original decision to make f C {x=3} mean f (C {x=3}) though I don’t think it received much debate at the time. I don’t want to perpetuate it. But it’s a judgement call, of course. I am strongly against the new option (6) because `f x.y` and `f (g x).y` mean very different things Yes, but `f M.x` and `(f M).x` mean very different things too. Nobody has any trouble with parsing M.x as a single lexeme. To be consistent with this approach, we should require `f (M.x)` for qualified names. Both option (4) and option (5) require just one new lexeme .X, and the rest can be handled in the parser. Same with (6), except that the lexing rule for dot-connected tokens becomes a bit simpler (because it’s less conditioned on where capital letters appear. Simon From: Iavor Diatchki Sent: 12 February 2020 17:58 To: Simon Marlow Cc: Simon Peyton Jones ; ghc-steering-committee ; Joachim Breitner Subject: Re: [ghc-steering-committee] Record dot notation Both option (4) and option (5) require just one new lexeme .X, and the rest can be handled in the parser. The difference between them is the precedence of selection, 4 has higher precedence than application (just like record update), while 5 has the same precedence as application. Most commonly, this would show up in examples like `f x.y`: with (4) this means `f (x.y)` with (5) this means `(f x).y`. Simon PJ, why do we need the special case for option (6), when it seems option (4) does the same thing in a simpler way? I am strongly against the new option (6) because `f x.y` and `f (g x).y` mean very different things, and being able to name and abstract expressions is one of the big selling point of Haskell. Also having a single consistent rule is a lot easier to teach and read, there really is no need for a special case here. -Iavor On Wed, Feb 12, 2020 at 8:44 AM Simon Marlow > wrote: On Wed, 12 Feb 2020 at 14:53, Simon Peyton Jones > wrote: Don’t forget option (6): like (5) but treat r.x as a lexeme. I find it hard to justify a language in which f M.x means f (M.x) but f m.x means (f m).x especially when the “.” means, in both cases, “take the x component of the thing on the left”. So here I’m leaning even harder on the connection with qualified names: let’s simply be consistent with that. I’m quite content to follow (5) on the meaning of f (g 3).x That is, it means the same as (f (g 3) .x), namely (f (g 3)).x Yes OK, I think that's reasonable. (I hadn't digested your earlier message proposing this properly, but I went back and re-read it just now.) I can imagine explaining that to someone - there's a straightforward lexical syntax, and the context-free grammar is similar to the rules for function application. Joachim what do you think? Cheers Simon But I’m very keen on maintaining consistency with qualified names when the thing on the LHS is a token (or dotted chain thereof.) Does anyone else have an alternative beyond 1-6 that they want to put forward? Simon From: ghc-steering-committee > On Behalf Of Simon Marlow Sent: 12 February 2020 11:21 To: Richard Eisenberg > Cc: ghc-steering-committee >; Joachim Breitner > Subject: Re: [ghc-steering-committee] Record dot notation On Mon, 10 Feb 2020 at 14:15, Richard Eisenberg > wrote: Upon careful consideration, I think the whitespace concerns here are somewhat ill-founded. First, please see https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0229-whitespace-bang-patterns.rst#proposed-change-specification, where (among other points), a careful description of "loose infix" vs "prefix" vs "suffix" vs "tight infix" is discussed. Here is a set of examples: a ! b -- a loose infix occurrence a!b -- a tight infix occurrence a !b -- a prefix occurrence a! b -- a suffix occurrence Yes and I was not very keen on that proposal (my concerns are on the discussion thread). This distinction is *not* just made by example, but that proposal (which has been accepted) defines these precisely. So, the comments on this thread about what counts as a naked selector are addressed: a naked selector is one where the dot is a prefix occurrence. Other whitespace-wariness comes from worrying about the distinction between prefix and tight infix occurrences. That is, should we differentiate between the interpretation of `f r.x` and `f r .x`. Yet in all versions of any of this, we differentiate between loose infix and the others. Thus there is *always* whitespace-sensitivity around dot. Note that this is true, as Simon PJ pointed out, regardless of this proposal, where a tight-infix usage of a dot with a capitalized identifier on the left is taken as a module qualification. In all of its versions, this proposal *increases* the whitespace sensitivity, by further distinguishing between prefix occurrences of dot and other usages. Let's compare options 3 and 5 with this analysis then: Option 3: loose-infix: whatever (.) is in scope tight-infix: - if left-hand is a capitalized identifier: module qualification - otherwise: record selection, binding tighter than function application prefix: postfix record selection, binding like function application suffix: presumably, whatever (.) is in scope Option 5: loose-infix: whatever (.) is in scope tight-infix: - if left-hand is a capitalized identifier: module qualification - otherwise: postfix record selection, binding like function application prefix: postfix record selection, binding like function application suffix: presumably, whatever (.) is in scope That's a good summary - but note that under Option 5 tight-infix and prefix are the same, modulo the qualified-identifier case, and this is the key difference. What I wanted to avoid was having to use the language of tight-infix vs. prefix AT ALL in understanding how record selection syntax works, and (5) achieves that whereas (3) doesn't. Under option 5 we get one new lexeme: . and everything else can be handled at the context-free grammar level. This is a nice minimal addition to the language. We don't have to invoke the mess that is proposal #229, which was forced upon us because BangPatterns and TypeApplications made the handling of (!) and (@) so complicated. If we don't have to do the same to (.), I believe we should take the opportunity to avoid it. Cheers Simon My point here is that option (5) is no more or less whitespace sensitive than option (3). Both need the same cases to figure what the period character in your code means. I think this is why Simon PJ has keyed this part of the debate to module qualification: that existing feature (not under debate) essentially breaks the symmetry here, meaning that we have more room to work with without breaking symmetry further. My vote is thus: 3 > 5 > 2 > 4 > 1 Other points of motivation: - Despite my argument above, I see the merit in (5). I just think that an argument "we don't want dot to be whitespace-sensitive" isn't really effective. - I want to accept this proposal. We're not going to get another go at this. - I really don't like the way record-update binds, and (4) reminds me too much of that. Richard On Feb 10, 2020, at 9:58 AM, Simon Marlow > wrote: On Fri, 7 Feb 2020 at 22:37, Joachim Breitner > wrote: I really would prefer a design where all these questions do not even need to be asked… Me too. Also what about (.x) vs. ( .x), are those the same? 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.) [...] 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. I'm also against whitespace-sensitivity and I lean towards this ordering too. But I'm going with: 5 > 2 > 1 > 4 > 3 Rationale: (5) seems the easiest to explain and has the fewest special cases, yet covers the use-cases we're interested in. Beyond that I want to be conservative because I find it hard to predict the ramifications of the more-complex alternatives 4/3, so I've put 2/1 ahead of those. I've made my peace with the current record selection syntax binding more tightly than application, and indeed I often rely on it to avoid a $, so I'm OK with 4 over 3. Cheers Simon 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/ _______________________________________________ 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 _______________________________________________ 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: From simonpj at microsoft.com Wed Feb 12 20:28:54 2020 From: simonpj at microsoft.com (Simon Peyton Jones) Date: Wed, 12 Feb 2020 20:28:54 +0000 Subject: [ghc-steering-committee] Record dot notation In-Reply-To: References: Message-ID: | 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? Cale, that is a reasonable question, but could you ask it on the GitHub thread, which is read/write to everyone, notably the authors, rather than to the (small) committee? There are 500+ comments on the proposal thread, at least some of which may help to answer your question. Looking for DAML repositories on GitHub will also lead you to real code (not just hypothetical) that uses the extension. DAML is essentially Haskell + this proposal, so (unusually for a proposal) we do have a substantial code base of existing code that uses the proposal. Much of it is inside Digital Asset, but some is public. Digital Asset considered the absence of record selection notation such a severe shortcoming that they would not have used Haskell if Neil had not implemented a fork of GHC that provided it. Your judgement may differ from theirs, but there is at least one group of production users that was willing to pay a high price to get it. To me this seems like a high benefit (to some), very low cost proposal. I suspect (but cannot prove) that this one change will make Haskell more approachable to a large class of users, especially those from an OO background. Simon | -----Original Message----- | From: Cale Gibbard | Sent: 11 February 2020 17:29 | To: Simon Peyton Jones | Cc: ghc-steering-committee at haskell.org | Subject: Re: [ghc-steering-committee] Record dot notation | | 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 | 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 | > Sent: 11 February 2020 07:59 | > To: Simon Peyton Jones | > 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 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://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgith | > ub.com%2Fshayne-fletcher-da%2Fghc-proposals%2Fblob%2Frecord-dot-syntax | > %2Fproposals%2F0000-record-dot-syntax.md&data=02%7C01%7Csimonpj%40 | > microsoft.com%7Ce47e02eaae144bce9ed108d7af17d7c1%7C72f988bf86f141af91a | > b2d7cd011db47%7C1%7C0%7C637170389249854748&sdata=jMD9cH%2FIhhpA3TT | > Ik6VCyXuJHUwkyuk%2Bn%2FprxJY5PxQ%3D&reserved=0 | > Lengthy discussion: | > https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgith | > ub.com%2Fghc-proposals%2Fghc-proposals%2Fpull%2F282&data=02%7C01%7 | > Csimonpj%40microsoft.com%7Ce47e02eaae144bce9ed108d7af17d7c1%7C72f988bf | > 86f141af91ab2d7cd011db47%7C1%7C0%7C637170389249854748&sdata=5MnVKO | > b85OV4QUi%2F3lVwnZGLv3kgnLr6MV3745PHLiI%3D&reserved=0 | > | > 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://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgitl | > ab.haskell.org%2Fghc%2Fghc%2Fwikis%2Frecords%2Foverloaded-record-field | > s&data=02%7C01%7Csimonpj%40microsoft.com%7Ce47e02eaae144bce9ed108d | > 7af17d7c1%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637170389249854 | > 748&sdata=8Sc4RHcN6qupZPHqgZWlxhBzOZ4Lj4wNIXGHnmdJLTo%3D&reser | > ved=0 | > | > * 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://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fmail | > .haskell.org%2Fcgi-bin%2Fmailman%2Flistinfo%2Fghc-steering-committee&a | > mp;data=02%7C01%7Csimonpj%40microsoft.com%7Ce47e02eaae144bce9ed108d7af | > 17d7c1%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637170389249864744 | > &sdata=5mvKBh3vIWVs9UhZNaQz3x7yQ41saU1r5UQNBIRcUnk%3D&reserved | > =0 | > | > _______________________________________________ | > ghc-steering-committee mailing list | > ghc-steering-committee at haskell.org | > https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fmail | > .haskell.org%2Fcgi-bin%2Fmailman%2Flistinfo%2Fghc-steering-committee&a | > mp;data=02%7C01%7Csimonpj%40microsoft.com%7Ce47e02eaae144bce9ed108d7af | > 17d7c1%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637170389249864744 | > &sdata=5mvKBh3vIWVs9UhZNaQz3x7yQ41saU1r5UQNBIRcUnk%3D&reserved | > =0 From mail at joachim-breitner.de Wed Feb 12 21:38:38 2020 From: mail at joachim-breitner.de (Joachim Breitner) Date: Wed, 12 Feb 2020 13:38:38 -0800 Subject: [ghc-steering-committee] Record dot notation In-Reply-To: References: Message-ID: Hi Cale, thanks for making sure the discussion isn’t just about whitespace, but also whether we want this at all! Am Dienstag, den 11.02.2020, 12:28 -0500 schrieb Cale Gibbard: > 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 My assumption here is that to some people, the lack for nice record access syntax is a big pain, else they would not bother with a proposal like this. In most of my Haskell programming, my own pain level wasn't too high (although prefixed field names are a bit ugly). I had one rather special case where I wish I could use Haskell as an “exectuable specification pseudocode langauge”, and the lack of nice record syntax killed that idea. This proposal might have helped some here (but only some, not all). So I can’t really refute your point that this might not be needed. You bring up some points about whether this doesn't go far enough (row polymorphism etc.). But this proposal really only add syntax for an existing feature (HasField), so maybe this is not the right place for a semantic critique of HasField? Of course it is a valid point to say that HasField is a feature that is not “good enough” to deserve a slice of the precious “.” operator. > 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 guess to some it isn't reasonable to write `f (getField @"lbl" r)`…? Cheers, Joachim -- Joachim Breitner mail at joachim-breitner.de http://www.joachim-breitner.de/ From cgibbard at gmail.com Wed Feb 12 22:53:11 2020 From: cgibbard at gmail.com (Cale Gibbard) Date: Wed, 12 Feb 2020 17:53:11 -0500 Subject: [ghc-steering-committee] Record dot notation In-Reply-To: References: Message-ID: I'm writing a longer comment reiterating the stuff I posted on this thread for the GitHub, thanks for pointing that discussion out Simon, I'd forgotten it was a thing that would naturally exist. It may be worth pointing out that we already have special syntax to help with using HasField, in the form of the OverloadedLabels. You can already do this to enable #lbl r as an alternative to getField @"lbl" r or any number of other permutations thereof if you'd prefer something slightly different: {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE TypeApplications #-} {-# LANGUAGE ScopedTypeVariables #-} import GHC.Records import GHC.OverloadedLabels (IsLabel(..)) import GHC.TypeLits (Symbol) instance forall x r a. HasField x r a => IsLabel x (r -> a) where fromLabel r = getField @x r On Wed, 12 Feb 2020 at 16:39, Joachim Breitner wrote: > > Hi Cale, > > thanks for making sure the discussion isn’t just about whitespace, but > also whether we want this at all! > > Am Dienstag, den 11.02.2020, 12:28 -0500 schrieb Cale Gibbard: > > 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 > > My assumption here is that to some people, the lack for nice record > access syntax is a big pain, else they would not bother with a proposal > like this. In most of my Haskell programming, my own pain level wasn't > too high (although prefixed field names are a bit ugly). I had one > rather special case where I wish I could use Haskell as an “exectuable > specification pseudocode langauge”, and the lack of nice record syntax > killed that idea. This proposal might have helped some here (but only > some, not all). > > So I can’t really refute your point that this might not be needed. > > > You bring up some points about whether this doesn't go far enough (row > polymorphism etc.). But this proposal really only add syntax for an > existing feature (HasField), so maybe this is not the right place for a > semantic critique of HasField? Of course it is a valid point to say > that HasField is a feature that is not “good enough” to deserve a slice > of the precious “.” operator. > > > > 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 guess to some it isn't reasonable to write `f (getField @"lbl" r)`…? > > Cheers, > Joachim > -- > Joachim Breitner > mail at joachim-breitner.de > http://www.joachim-breitner.de/ > > > _______________________________________________ > ghc-steering-committee mailing list > ghc-steering-committee at haskell.org > https://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-steering-committee From marlowsd at gmail.com Thu Feb 13 08:19:27 2020 From: marlowsd at gmail.com (Simon Marlow) Date: Thu, 13 Feb 2020 08:19:27 +0000 Subject: [ghc-steering-committee] Record dot notation In-Reply-To: References: Message-ID: On Wed, 12 Feb 2020 at 20:05, Simon Peyton Jones wrote: > > > Both option (4) and option (5) require just one new lexeme .X, and the > rest can be handled in the parser. > > > > Same with (6), except that the lexing rule for dot-connected tokens > becomes a bit simpler (because it’s less conditioned on where capital > letters appear. > I suspect in the case of (6) we would want record selection to be a different lexeme from qvarid, because qvarid occurs in lots of places where record selection wouldn't make sense: import/export lists, type variables, etc. If they were the same lexeme we'd have to weed out all the error cases post-parsing or have explicit checks in the parser, both of which are harder than just recognising the grammar precisely in the first place. Cheers Simon > > Simon > > > > *From:* Iavor Diatchki > *Sent:* 12 February 2020 17:58 > *To:* Simon Marlow > *Cc:* Simon Peyton Jones ; ghc-steering-committee < > ghc-steering-committee at haskell.org>; Joachim Breitner < > mail at joachim-breitner.de> > *Subject:* Re: [ghc-steering-committee] Record dot notation > > > > Both option (4) and option (5) require just one new lexeme .X, and the > rest can be handled in the parser. The difference between them is the > precedence of selection, 4 has higher precedence than application (just > like record update), while 5 has the same precedence as application. Most > commonly, this would show up in examples like `f x.y`: with (4) this means > `f (x.y)` with (5) this means `(f x).y`. > > > > Simon PJ, why do we need the special case for option (6), when it seems > option (4) does the same thing in a simpler way? > > > > I am strongly against the new option (6) because `f x.y` and `f (g x).y` > mean very different things, and being able to name and abstract expressions > is one of the big selling point of Haskell. Also having a single > consistent rule is a lot easier to teach and read, there really is no need > for a special case here. > > > > -Iavor > > > > > > > > > > > > On Wed, Feb 12, 2020 at 8:44 AM Simon Marlow wrote: > > On Wed, 12 Feb 2020 at 14:53, Simon Peyton Jones > wrote: > > Don’t forget option (6): like (5) but treat r.x as a lexeme. > > > > I find it hard to justify a language in which > > f M.x means f (M.x) > > but f m.x means (f m).x > > > > especially when the “.” means, in both cases, “take the x component of the > thing on the left”. > > > > So here I’m leaning even harder on the connection with qualified names: > let’s simply be consistent with that. > > > > I’m quite content to follow (5) on the meaning of > > f (g 3).x > > That is, it means the same as (f (g 3) .x), namely (f (g 3)).x > > > > Yes OK, I think that's reasonable. (I hadn't digested your earlier message > proposing this properly, but I went back and re-read it just now.) > > > > I can imagine explaining that to someone - there's a straightforward > lexical syntax, and the context-free grammar is similar to the rules for > function application. > > > > Joachim what do you think? > > > > Cheers > > Simon > > > > > > But I’m very keen on maintaining consistency with qualified names when the > thing on the LHS is a token (or dotted chain thereof.) > > > > Does anyone else have an alternative beyond 1-6 that they want to put > forward? > > > > Simon > > > > *From:* ghc-steering-committee > *On Behalf Of *Simon Marlow > *Sent:* 12 February 2020 11:21 > *To:* Richard Eisenberg > *Cc:* ghc-steering-committee ; > Joachim Breitner > *Subject:* Re: [ghc-steering-committee] Record dot notation > > > > > > On Mon, 10 Feb 2020 at 14:15, Richard Eisenberg wrote: > > Upon careful consideration, I think the whitespace concerns here are > somewhat ill-founded. > > > > First, please see > https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0229-whitespace-bang-patterns.rst#proposed-change-specification > , > where (among other points), a careful description of "loose infix" vs > "prefix" vs "suffix" vs "tight infix" is discussed. Here is a set of > examples: > > a ! b -- a loose infix occurrence > > a!b -- a tight infix occurrence > > a !b -- a prefix occurrence > > a! b -- a suffix occurrence > > Yes and I was not very keen on that proposal (my concerns are on the > discussion thread). > > > > This distinction is *not* just made by example, but that proposal (which > has been accepted) defines these precisely. So, the comments on this thread > about what counts as a naked selector are addressed: a naked selector is > one where the dot is a prefix occurrence. > > > > Other whitespace-wariness comes from worrying about the distinction > between prefix and tight infix occurrences. That is, should we > differentiate between the interpretation of `f r.x` and `f r .x`. Yet in > all versions of any of this, we differentiate between loose infix and the > others. Thus there is *always* whitespace-sensitivity around dot. Note that > this is true, as Simon PJ pointed out, regardless of this proposal, where a > tight-infix usage of a dot with a capitalized identifier on the left is > taken as a module qualification. In all of its versions, this proposal > *increases* the whitespace sensitivity, by further distinguishing between > prefix occurrences of dot and other usages. > > > > Let's compare options 3 and 5 with this analysis then: > > > > Option 3: > > loose-infix: whatever (.) is in scope > > tight-infix: > > - if left-hand is a capitalized identifier: module qualification > > - otherwise: record selection, binding tighter than function application > > prefix: postfix record selection, binding like function application > > suffix: presumably, whatever (.) is in scope > > > > Option 5: > > loose-infix: whatever (.) is in scope > > tight-infix: > > - if left-hand is a capitalized identifier: module qualification > > - otherwise: postfix record selection, binding like function application > > prefix: postfix record selection, binding like function application > > suffix: presumably, whatever (.) is in scope > > > > That's a good summary - but note that under Option 5 tight-infix and > prefix are the same, modulo the qualified-identifier case, and this is the > key difference. What I wanted to avoid was having to use the language of > tight-infix vs. prefix AT ALL in understanding how record selection syntax > works, and (5) achieves that whereas (3) doesn't. > > > > Under option 5 we get one new lexeme: > > . > > and everything else can be handled at the context-free grammar level. This > is a nice minimal addition to the language. We don't have to invoke the > mess that is proposal #229, which was forced upon us because BangPatterns > and TypeApplications made the handling of (!) and (@) so complicated. If we > don't have to do the same to (.), I believe we should take the opportunity > to avoid it. > > > > Cheers > > Simon > > > > > > My point here is that option (5) is no more or less whitespace sensitive > than option (3). Both need the same cases to figure what the period > character in your code means. I think this is why Simon PJ has keyed this > part of the debate to module qualification: that existing feature (not > under debate) essentially breaks the symmetry here, meaning that we have > more room to work with without breaking symmetry further. > > > > My vote is thus: > > > > 3 > 5 > 2 > 4 > 1 > > > > Other points of motivation: > > - Despite my argument above, I see the merit in (5). I just think that an > argument "we don't want dot to be whitespace-sensitive" isn't really > effective. > > - I want to accept this proposal. We're not going to get another go at > this. > > - I really don't like the way record-update binds, and (4) reminds me too > much of that. > > > > Richard > > > > On Feb 10, 2020, at 9:58 AM, Simon Marlow wrote: > > > > On Fri, 7 Feb 2020 at 22:37, Joachim Breitner > wrote: > > > I really would prefer a design where all these questions do not even > need to be asked… > > > > Me too. Also what about (.x) vs. ( .x), are those the same? > > > > 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.) > > > > [...] > > > > 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. > > > > I'm also against whitespace-sensitivity and I lean towards this ordering > too. > > But I'm going with: > > > > 5 > 2 > 1 > 4 > 3 > > > > Rationale: (5) seems the easiest to explain and has the fewest special > cases, yet covers the use-cases we're interested in. Beyond that I want to > be conservative because I find it hard to predict the ramifications of the > more-complex alternatives 4/3, so I've put 2/1 ahead of those. I've made my > peace with the current record selection syntax binding more tightly than > application, and indeed I often rely on it to avoid a $, so I'm OK with 4 > over 3. > > > > Cheers > > Simon > > > > > > > > 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/ > > > > _______________________________________________ > 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 > > > > > _______________________________________________ > 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: From simonpj at microsoft.com Thu Feb 13 08:46:52 2020 From: simonpj at microsoft.com (Simon Peyton Jones) Date: Thu, 13 Feb 2020 08:46:52 +0000 Subject: [ghc-steering-committee] Record dot notation In-Reply-To: References: Message-ID: | I'm writing a longer comment reiterating the stuff I posted on this | thread for the GitHub, thanks for pointing that discussion out Simon, | I'd forgotten it was a thing that would naturally exist. Thanks Cale. Please do read your way into the thread. It is long, but we owe it to the people who took the time to post during the extended discussion that took place, when many of these issues were debated. Simon | -----Original Message----- | From: ghc-steering-committee | On Behalf Of Cale Gibbard | Sent: 12 February 2020 22:53 | To: Joachim Breitner | Cc: ghc-steering-committee | Subject: Re: [ghc-steering-committee] Record dot notation | | I'm writing a longer comment reiterating the stuff I posted on this | thread for the GitHub, thanks for pointing that discussion out Simon, | I'd forgotten it was a thing that would naturally exist. | | It may be worth pointing out that we already have special syntax to | help with using HasField, in the form of the OverloadedLabels. You can | already do this to enable #lbl r as an alternative to getField @"lbl" | r or any number of other permutations thereof if you'd prefer | something slightly different: | | {-# LANGUAGE FlexibleInstances #-} | {-# LANGUAGE MultiParamTypeClasses #-} | {-# LANGUAGE TypeApplications #-} | {-# LANGUAGE ScopedTypeVariables #-} | | import GHC.Records | import GHC.OverloadedLabels (IsLabel(..)) | import GHC.TypeLits (Symbol) | | instance forall x r a. HasField x r a => IsLabel x (r -> a) where | fromLabel r = getField @x r | | On Wed, 12 Feb 2020 at 16:39, Joachim Breitner | wrote: | > | > Hi Cale, | > | > thanks for making sure the discussion isn’t just about whitespace, but | > also whether we want this at all! | > | > Am Dienstag, den 11.02.2020, 12:28 -0500 schrieb Cale Gibbard: | > > 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 | > | > My assumption here is that to some people, the lack for nice record | > access syntax is a big pain, else they would not bother with a proposal | > like this. In most of my Haskell programming, my own pain level wasn't | > too high (although prefixed field names are a bit ugly). I had one | > rather special case where I wish I could use Haskell as an “exectuable | > specification pseudocode langauge”, and the lack of nice record syntax | > killed that idea. This proposal might have helped some here (but only | > some, not all). | > | > So I can’t really refute your point that this might not be needed. | > | > | > You bring up some points about whether this doesn't go far enough (row | > polymorphism etc.). But this proposal really only add syntax for an | > existing feature (HasField), so maybe this is not the right place for a | > semantic critique of HasField? Of course it is a valid point to say | > that HasField is a feature that is not “good enough” to deserve a slice | > of the precious “.” operator. | > | > | > > 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 guess to some it isn't reasonable to write `f (getField @"lbl" r)`…? | > | > Cheers, | > Joachim | > -- | > Joachim Breitner | > mail at joachim-breitner.de | > | https://nam06.safelinks.protection.outlook.com/?url=http%3A%2F%2Fwww.joach | im- | breitner.de%2F&data=02%7C01%7Csimonpj%40microsoft.com%7C4e16c822e6d840 | db64eb08d7b00e655a%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C6371714481 | 89027667&sdata=GM8ZfvbDJb%2BmQbYo3OG%2BHuBy6wBir8eu2LArbng6W%2BI%3D&am | p;reserved=0 | > | > | > _______________________________________________ | > ghc-steering-committee mailing list | > ghc-steering-committee at haskell.org | > | https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fmail.has | kell.org%2Fcgi-bin%2Fmailman%2Flistinfo%2Fghc-steering- | committee&data=02%7C01%7Csimonpj%40microsoft.com%7C4e16c822e6d840db64e | b08d7b00e655a%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637171448189027 | 667&sdata=gipdn8dzyetZQMt5AHB4K3Bjxzf66Wu%2FT5yeMFpEcnw%3D&reserve | d=0 | _______________________________________________ | ghc-steering-committee mailing list | ghc-steering-committee at haskell.org | https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fmail.has | kell.org%2Fcgi-bin%2Fmailman%2Flistinfo%2Fghc-steering- | committee&data=02%7C01%7Csimonpj%40microsoft.com%7C4e16c822e6d840db64e | b08d7b00e655a%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637171448189027 | 667&sdata=gipdn8dzyetZQMt5AHB4K3Bjxzf66Wu%2FT5yeMFpEcnw%3D&reserve | d=0 From iavor.diatchki at gmail.com Thu Feb 13 17:55:49 2020 From: iavor.diatchki at gmail.com (Iavor Diatchki) Date: Thu, 13 Feb 2020 09:55:49 -0800 Subject: [ghc-steering-committee] Record dot notation In-Reply-To: References: Message-ID: On Wed, Feb 12, 2020 at 12:05 PM Simon Peyton Jones wrote: > > > > Yes, but `f M.x` and `(f M).x` mean very different things too. Nobody has > any trouble with parsing M.x as a single lexeme. To be consistent with > this approach, we should require `f (M.x)` for qualified names. > > > > Both option (4) and option (5) require just one new lexeme .X, and the > rest can be handled in the parser. > > > I don't really understand your example: why would a programmer expect `f M.x` and `(f M).x` to mean the same thing? Or when would you want to perform this transformation on an existing program? It doesn't even make sense to apply a function to a module name... This is not at all the case with record selection: I can absolutely see myself writing the expression `f r.x`, and later decide that maybe I want to apply a function to `r` before selecting: `f (g r).x`. Except that with proposal (6) this actually means something very different, and *at best* I'd get a confusing type error, and at worst, I'd silently get a completely different behavior. -Iavor > > > *From:* Iavor Diatchki > *Sent:* 12 February 2020 17:58 > *To:* Simon Marlow > *Cc:* Simon Peyton Jones ; ghc-steering-committee < > ghc-steering-committee at haskell.org>; Joachim Breitner < > mail at joachim-breitner.de> > *Subject:* Re: [ghc-steering-committee] Record dot notation > > > > Both option (4) and option (5) require just one new lexeme .X, and the > rest can be handled in the parser. The difference between them is the > precedence of selection, 4 has higher precedence than application (just > like record update), while 5 has the same precedence as application. Most > commonly, this would show up in examples like `f x.y`: with (4) this means > `f (x.y)` with (5) this means `(f x).y`. > > > > Simon PJ, why do we need the special case for option (6), when it seems > option (4) does the same thing in a simpler way? > > > > I am strongly against the new option (6) because `f x.y` and `f (g x).y` > mean very different things, and being able to name and abstract expressions > is one of the big selling point of Haskell. Also having a single > consistent rule is a lot easier to teach and read, there really is no need > for a special case here. > > > > -Iavor > > > > > > > > > > > > On Wed, Feb 12, 2020 at 8:44 AM Simon Marlow wrote: > > On Wed, 12 Feb 2020 at 14:53, Simon Peyton Jones > wrote: > > Don’t forget option (6): like (5) but treat r.x as a lexeme. > > > > I find it hard to justify a language in which > > f M.x means f (M.x) > > but f m.x means (f m).x > > > > especially when the “.” means, in both cases, “take the x component of the > thing on the left”. > > > > So here I’m leaning even harder on the connection with qualified names: > let’s simply be consistent with that. > > > > I’m quite content to follow (5) on the meaning of > > f (g 3).x > > That is, it means the same as (f (g 3) .x), namely (f (g 3)).x > > > > Yes OK, I think that's reasonable. (I hadn't digested your earlier message > proposing this properly, but I went back and re-read it just now.) > > > > I can imagine explaining that to someone - there's a straightforward > lexical syntax, and the context-free grammar is similar to the rules for > function application. > > > > Joachim what do you think? > > > > Cheers > > Simon > > > > > > But I’m very keen on maintaining consistency with qualified names when the > thing on the LHS is a token (or dotted chain thereof.) > > > > Does anyone else have an alternative beyond 1-6 that they want to put > forward? > > > > Simon > > > > *From:* ghc-steering-committee > *On Behalf Of *Simon Marlow > *Sent:* 12 February 2020 11:21 > *To:* Richard Eisenberg > *Cc:* ghc-steering-committee ; > Joachim Breitner > *Subject:* Re: [ghc-steering-committee] Record dot notation > > > > > > On Mon, 10 Feb 2020 at 14:15, Richard Eisenberg wrote: > > Upon careful consideration, I think the whitespace concerns here are > somewhat ill-founded. > > > > First, please see > https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0229-whitespace-bang-patterns.rst#proposed-change-specification > , > where (among other points), a careful description of "loose infix" vs > "prefix" vs "suffix" vs "tight infix" is discussed. Here is a set of > examples: > > a ! b -- a loose infix occurrence > > a!b -- a tight infix occurrence > > a !b -- a prefix occurrence > > a! b -- a suffix occurrence > > Yes and I was not very keen on that proposal (my concerns are on the > discussion thread). > > > > This distinction is *not* just made by example, but that proposal (which > has been accepted) defines these precisely. So, the comments on this thread > about what counts as a naked selector are addressed: a naked selector is > one where the dot is a prefix occurrence. > > > > Other whitespace-wariness comes from worrying about the distinction > between prefix and tight infix occurrences. That is, should we > differentiate between the interpretation of `f r.x` and `f r .x`. Yet in > all versions of any of this, we differentiate between loose infix and the > others. Thus there is *always* whitespace-sensitivity around dot. Note that > this is true, as Simon PJ pointed out, regardless of this proposal, where a > tight-infix usage of a dot with a capitalized identifier on the left is > taken as a module qualification. In all of its versions, this proposal > *increases* the whitespace sensitivity, by further distinguishing between > prefix occurrences of dot and other usages. > > > > Let's compare options 3 and 5 with this analysis then: > > > > Option 3: > > loose-infix: whatever (.) is in scope > > tight-infix: > > - if left-hand is a capitalized identifier: module qualification > > - otherwise: record selection, binding tighter than function application > > prefix: postfix record selection, binding like function application > > suffix: presumably, whatever (.) is in scope > > > > Option 5: > > loose-infix: whatever (.) is in scope > > tight-infix: > > - if left-hand is a capitalized identifier: module qualification > > - otherwise: postfix record selection, binding like function application > > prefix: postfix record selection, binding like function application > > suffix: presumably, whatever (.) is in scope > > > > That's a good summary - but note that under Option 5 tight-infix and > prefix are the same, modulo the qualified-identifier case, and this is the > key difference. What I wanted to avoid was having to use the language of > tight-infix vs. prefix AT ALL in understanding how record selection syntax > works, and (5) achieves that whereas (3) doesn't. > > > > Under option 5 we get one new lexeme: > > . > > and everything else can be handled at the context-free grammar level. This > is a nice minimal addition to the language. We don't have to invoke the > mess that is proposal #229, which was forced upon us because BangPatterns > and TypeApplications made the handling of (!) and (@) so complicated. If we > don't have to do the same to (.), I believe we should take the opportunity > to avoid it. > > > > Cheers > > Simon > > > > > > My point here is that option (5) is no more or less whitespace sensitive > than option (3). Both need the same cases to figure what the period > character in your code means. I think this is why Simon PJ has keyed this > part of the debate to module qualification: that existing feature (not > under debate) essentially breaks the symmetry here, meaning that we have > more room to work with without breaking symmetry further. > > > > My vote is thus: > > > > 3 > 5 > 2 > 4 > 1 > > > > Other points of motivation: > > - Despite my argument above, I see the merit in (5). I just think that an > argument "we don't want dot to be whitespace-sensitive" isn't really > effective. > > - I want to accept this proposal. We're not going to get another go at > this. > > - I really don't like the way record-update binds, and (4) reminds me too > much of that. > > > > Richard > > > > On Feb 10, 2020, at 9:58 AM, Simon Marlow wrote: > > > > On Fri, 7 Feb 2020 at 22:37, Joachim Breitner > wrote: > > > I really would prefer a design where all these questions do not even > need to be asked… > > > > Me too. Also what about (.x) vs. ( .x), are those the same? > > > > 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.) > > > > [...] > > > > 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. > > > > I'm also against whitespace-sensitivity and I lean towards this ordering > too. > > But I'm going with: > > > > 5 > 2 > 1 > 4 > 3 > > > > Rationale: (5) seems the easiest to explain and has the fewest special > cases, yet covers the use-cases we're interested in. Beyond that I want to > be conservative because I find it hard to predict the ramifications of the > more-complex alternatives 4/3, so I've put 2/1 ahead of those. I've made my > peace with the current record selection syntax binding more tightly than > application, and indeed I often rely on it to avoid a $, so I'm OK with 4 > over 3. > > > > Cheers > > Simon > > > > > > > > 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/ > > > > _______________________________________________ > 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 > > > > > _______________________________________________ > 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: From simonpj at microsoft.com Thu Feb 13 22:10:14 2020 From: simonpj at microsoft.com (Simon Peyton Jones) Date: Thu, 13 Feb 2020 22:10:14 +0000 Subject: [ghc-steering-committee] Record dot notation In-Reply-To: References: Message-ID: I don't really understand your example: why would a programmer expect `f M.x` and `(f M).x` to mean the same thing? Or when would you want to perform this transformation on an existing program? It doesn't even make sense to apply a function to a module name... Well, if we didn’t have qualified names then of course (f M.x) would mean (f M) . x that is, f applied to the data constructor M, composed with x. But we do have qualified names, and thus regard M.x (with no spaces) as binding tighter than function application. One way to think of it (and the way it is implemented) is to think of M.x as a lexeme. I’m just saying that I think it’s be deeply strange to parse (f M.x) in one way, and (f m.x) in a completely different way, especially when (M.x) and (m.x) both have the same informal reading: “take the x component of M or m resp”. I’m just seeking lexical and syntactic consistency. Yes I know that today we do indeed parse these two utterly differently, and that’s reason I never write function composition without spaces around it. Let’s take the opportunity to fix this 😊. No one has suggested any new alternatives, so it probably makes sense for me to put forward a slate of possibilities to vote on. But not tonight. Simon From: Iavor Diatchki Sent: 13 February 2020 17:56 To: Simon Peyton Jones Cc: Simon Marlow ; ghc-steering-committee ; Joachim Breitner Subject: Re: [ghc-steering-committee] Record dot notation On Wed, Feb 12, 2020 at 12:05 PM Simon Peyton Jones > wrote: Yes, but `f M.x` and `(f M).x` mean very different things too. Nobody has any trouble with parsing M.x as a single lexeme. To be consistent with this approach, we should require `f (M.x)` for qualified names. Both option (4) and option (5) require just one new lexeme .X, and the rest can be handled in the parser. I don't really understand your example: why would a programmer expect `f M.x` and `(f M).x` to mean the same thing? Or when would you want to perform this transformation on an existing program? It doesn't even make sense to apply a function to a module name... This is not at all the case with record selection: I can absolutely see myself writing the expression `f r.x`, and later decide that maybe I want to apply a function to `r` before selecting: `f (g r).x`. Except that with proposal (6) this actually means something very different, and *at best* I'd get a confusing type error, and at worst, I'd silently get a completely different behavior. -Iavor From: Iavor Diatchki > Sent: 12 February 2020 17:58 To: Simon Marlow > Cc: Simon Peyton Jones >; ghc-steering-committee >; Joachim Breitner > Subject: Re: [ghc-steering-committee] Record dot notation Both option (4) and option (5) require just one new lexeme .X, and the rest can be handled in the parser. The difference between them is the precedence of selection, 4 has higher precedence than application (just like record update), while 5 has the same precedence as application. Most commonly, this would show up in examples like `f x.y`: with (4) this means `f (x.y)` with (5) this means `(f x).y`. Simon PJ, why do we need the special case for option (6), when it seems option (4) does the same thing in a simpler way? I am strongly against the new option (6) because `f x.y` and `f (g x).y` mean very different things, and being able to name and abstract expressions is one of the big selling point of Haskell. Also having a single consistent rule is a lot easier to teach and read, there really is no need for a special case here. -Iavor On Wed, Feb 12, 2020 at 8:44 AM Simon Marlow > wrote: On Wed, 12 Feb 2020 at 14:53, Simon Peyton Jones > wrote: Don’t forget option (6): like (5) but treat r.x as a lexeme. I find it hard to justify a language in which f M.x means f (M.x) but f m.x means (f m).x especially when the “.” means, in both cases, “take the x component of the thing on the left”. So here I’m leaning even harder on the connection with qualified names: let’s simply be consistent with that. I’m quite content to follow (5) on the meaning of f (g 3).x That is, it means the same as (f (g 3) .x), namely (f (g 3)).x Yes OK, I think that's reasonable. (I hadn't digested your earlier message proposing this properly, but I went back and re-read it just now.) I can imagine explaining that to someone - there's a straightforward lexical syntax, and the context-free grammar is similar to the rules for function application. Joachim what do you think? Cheers Simon But I’m very keen on maintaining consistency with qualified names when the thing on the LHS is a token (or dotted chain thereof.) Does anyone else have an alternative beyond 1-6 that they want to put forward? Simon From: ghc-steering-committee > On Behalf Of Simon Marlow Sent: 12 February 2020 11:21 To: Richard Eisenberg > Cc: ghc-steering-committee >; Joachim Breitner > Subject: Re: [ghc-steering-committee] Record dot notation On Mon, 10 Feb 2020 at 14:15, Richard Eisenberg > wrote: Upon careful consideration, I think the whitespace concerns here are somewhat ill-founded. First, please see https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0229-whitespace-bang-patterns.rst#proposed-change-specification, where (among other points), a careful description of "loose infix" vs "prefix" vs "suffix" vs "tight infix" is discussed. Here is a set of examples: a ! b -- a loose infix occurrence a!b -- a tight infix occurrence a !b -- a prefix occurrence a! b -- a suffix occurrence Yes and I was not very keen on that proposal (my concerns are on the discussion thread). This distinction is *not* just made by example, but that proposal (which has been accepted) defines these precisely. So, the comments on this thread about what counts as a naked selector are addressed: a naked selector is one where the dot is a prefix occurrence. Other whitespace-wariness comes from worrying about the distinction between prefix and tight infix occurrences. That is, should we differentiate between the interpretation of `f r.x` and `f r .x`. Yet in all versions of any of this, we differentiate between loose infix and the others. Thus there is *always* whitespace-sensitivity around dot. Note that this is true, as Simon PJ pointed out, regardless of this proposal, where a tight-infix usage of a dot with a capitalized identifier on the left is taken as a module qualification. In all of its versions, this proposal *increases* the whitespace sensitivity, by further distinguishing between prefix occurrences of dot and other usages. Let's compare options 3 and 5 with this analysis then: Option 3: loose-infix: whatever (.) is in scope tight-infix: - if left-hand is a capitalized identifier: module qualification - otherwise: record selection, binding tighter than function application prefix: postfix record selection, binding like function application suffix: presumably, whatever (.) is in scope Option 5: loose-infix: whatever (.) is in scope tight-infix: - if left-hand is a capitalized identifier: module qualification - otherwise: postfix record selection, binding like function application prefix: postfix record selection, binding like function application suffix: presumably, whatever (.) is in scope That's a good summary - but note that under Option 5 tight-infix and prefix are the same, modulo the qualified-identifier case, and this is the key difference. What I wanted to avoid was having to use the language of tight-infix vs. prefix AT ALL in understanding how record selection syntax works, and (5) achieves that whereas (3) doesn't. Under option 5 we get one new lexeme: . and everything else can be handled at the context-free grammar level. This is a nice minimal addition to the language. We don't have to invoke the mess that is proposal #229, which was forced upon us because BangPatterns and TypeApplications made the handling of (!) and (@) so complicated. If we don't have to do the same to (.), I believe we should take the opportunity to avoid it. Cheers Simon My point here is that option (5) is no more or less whitespace sensitive than option (3). Both need the same cases to figure what the period character in your code means. I think this is why Simon PJ has keyed this part of the debate to module qualification: that existing feature (not under debate) essentially breaks the symmetry here, meaning that we have more room to work with without breaking symmetry further. My vote is thus: 3 > 5 > 2 > 4 > 1 Other points of motivation: - Despite my argument above, I see the merit in (5). I just think that an argument "we don't want dot to be whitespace-sensitive" isn't really effective. - I want to accept this proposal. We're not going to get another go at this. - I really don't like the way record-update binds, and (4) reminds me too much of that. Richard On Feb 10, 2020, at 9:58 AM, Simon Marlow > wrote: On Fri, 7 Feb 2020 at 22:37, Joachim Breitner > wrote: I really would prefer a design where all these questions do not even need to be asked… Me too. Also what about (.x) vs. ( .x), are those the same? 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.) [...] 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. I'm also against whitespace-sensitivity and I lean towards this ordering too. But I'm going with: 5 > 2 > 1 > 4 > 3 Rationale: (5) seems the easiest to explain and has the fewest special cases, yet covers the use-cases we're interested in. Beyond that I want to be conservative because I find it hard to predict the ramifications of the more-complex alternatives 4/3, so I've put 2/1 ahead of those. I've made my peace with the current record selection syntax binding more tightly than application, and indeed I often rely on it to avoid a $, so I'm OK with 4 over 3. Cheers Simon 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/ _______________________________________________ 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 _______________________________________________ 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: From mail at joachim-breitner.de Sun Feb 23 08:48:29 2020 From: mail at joachim-breitner.de (Joachim Breitner) Date: Sun, 23 Feb 2020 09:48:29 +0100 Subject: [ghc-steering-committee] Please review #302: Layout and Guards in Lambda Expressions, Shepherd: Cale Message-ID: <7a70013f536cff699ae303163e7611991c9b4569.camel@joachim-breitner.de> Dear Committee, this is your secretary speaking: Layout and Guards in Lambda Expressions has been proposed by Jakob Brünker https://github.com/ghc-proposals/ghc-proposals/pull/302 https://github.com/JakobBruenker/ghc-proposals/blob/patch-1/proposals/0000-lambda-layout.md I propose Cale Gibbard as the shepherd, so keep our new guys busy. Please guide us to a conclusion as outlined in https://github.com/ghc-proposals/ghc-proposals#committee-process Thanks, Joachim -- Joachim Breitner mail at joachim-breitner.de http://www.joachim-breitner.de/