From mail at joachim-breitner.de Thu Mar 1 05:15:15 2018 From: mail at joachim-breitner.de (Joachim Breitner) Date: Thu, 01 Mar 2018 00:15:15 -0500 Subject: [ghc-steering-committee] Please Review: Scoped Type variables for existentials, Shepherd: Roman Message-ID: <1519881315.24339.2.camel@joachim-breitner.de> Dear Committee, this is your secretary speaking: Scoped Type variables for existentials by Emmanuel “Emma” Suarez, with help from Richard Eisenberg and Stephanie Weirich. https://github.com/ghc-proposals/ghc-proposals/pull/96 I propose Roman Leshchinskiy as the shepherd. Roman, please reach consensus as described in https://github.com/ghc-proposals/ghc-proposals#committee-process I suggest you make a recommendation, in a new e-mail thread, about the decision, maybe point out debatable points, and assume that anyone who stays quiet agrees with you. Thanks, -- Joachim Breitner mail at joachim-breitner.de http://www.joachim-breitner.de/ -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 833 bytes Desc: This is a digitally signed message part URL: From mail at joachim-breitner.de Thu Mar 1 05:17:46 2018 From: mail at joachim-breitner.de (Joachim Breitner) Date: Thu, 01 Mar 2018 00:17:46 -0500 Subject: [ghc-steering-committee] Please review: Mutable constructor fields, Shepherd: Ryan Newton In-Reply-To: References: <1500034660.7133.5.camel@joachim-breitner.de> <33016754-2802-47E0-87B3-0BBD80C12FFE@cs.brynmawr.edu> Message-ID: <1519881466.24339.4.camel@joachim-breitner.de> Hi, Am Freitag, den 23.02.2018, 15:22 -0500 schrieb Ryan Newton: > Ok, I'm not hearing any strong objections and over the long course of > discussion in various venues, reactions have been mostly positive. > Since committee discussion here has died down, I move to go ahead and > accept this proposal if there are no further objections. it has been quiet here, but I see new activity on https://github.com/ghc-proposals/ghc-proposals/pull/8 Is this a sign that the proposal is not yet as polished as would hope for? Joachim -- Joachim “nomeata” Breitner mail at joachim-breitner.de https://www.joachim-breitner.de/ -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 833 bytes Desc: This is a digitally signed message part URL: From mail at joachim-breitner.de Thu Mar 1 05:20:39 2018 From: mail at joachim-breitner.de (Joachim Breitner) Date: Thu, 01 Mar 2018 00:20:39 -0500 Subject: [ghc-steering-committee] Please review: Int8/Word8, Shepherd: Simon Marlow In-Reply-To: References: <1518061232.1186.1.camel@joachim-breitner.de> Message-ID: <1519881639.24339.5.camel@joachim-breitner.de> Hi, Am Donnerstag, den 22.02.2018, 11:46 +0000 schrieb Simon Marlow: > I recommend that we accept this proposal. I see clear consensus -- accepted! Joachim -- Joachim Breitner mail at joachim-breitner.de http://www.joachim-breitner.de/ -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 833 bytes Desc: This is a digitally signed message part URL: From mail at joachim-breitner.de Thu Mar 1 05:23:19 2018 From: mail at joachim-breitner.de (Joachim Breitner) Date: Thu, 01 Mar 2018 00:23:19 -0500 Subject: [ghc-steering-committee] Type-level type applications (#80): Recommend accept In-Reply-To: References: Message-ID: <1519881799.24339.6.camel@joachim-breitner.de> Hi, Am Freitag, den 23.02.2018, 15:32 -0500 schrieb Richard Eisenberg: > I believe strongly we should accept. There was no substantive dissenting commentary, just clarifying questions. Clear and vocal consensus observed, accepted. Joachim -- Joachim Breitner mail at joachim-breitner.de http://www.joachim-breitner.de/ -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 833 bytes Desc: This is a digitally signed message part URL: From marlowsd at gmail.com Thu Mar 1 08:48:56 2018 From: marlowsd at gmail.com (Simon Marlow) Date: Thu, 1 Mar 2018 08:48:56 +0000 Subject: [ghc-steering-committee] Please review: Mutable constructor fields, Shepherd: Ryan Newton In-Reply-To: <1519881466.24339.4.camel@joachim-breitner.de> References: <1500034660.7133.5.camel@joachim-breitner.de> <33016754-2802-47E0-87B3-0BBD80C12FFE@cs.brynmawr.edu> <1519881466.24339.4.camel@joachim-breitner.de> Message-ID: Simon has provided a detailed review (thanks!) so I think we'll need some time to digest those comments and suggestions and modify the proposal. In light of that shall we put the proposal back into the discussion phase for now? Cheers Simon On 1 March 2018 at 05:17, Joachim Breitner wrote: > Hi, > > Am Freitag, den 23.02.2018, 15:22 -0500 schrieb Ryan Newton: > > Ok, I'm not hearing any strong objections and over the long course of > > discussion in various venues, reactions have been mostly positive. > > Since committee discussion here has died down, I move to go ahead and > > accept this proposal if there are no further objections. > > it has been quiet here, but I see new activity on > https://github.com/ghc-proposals/ghc-proposals/pull/8 > > Is this a sign that the proposal is not yet as polished as would hope > for? > > Joachim > > -- > Joachim “nomeata” Breitner > mail at joachim-breitner.de > https://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 simonpj at microsoft.com Thu Mar 1 08:54:27 2018 From: simonpj at microsoft.com (Simon Peyton Jones) Date: Thu, 1 Mar 2018 08:54:27 +0000 Subject: [ghc-steering-committee] Please review: Mutable constructor fields, Shepherd: Ryan Newton In-Reply-To: References: <1500034660.7133.5.camel@joachim-breitner.de> <33016754-2802-47E0-87B3-0BBD80C12FFE@cs.brynmawr.edu> <1519881466.24339.4.camel@joachim-breitner.de> Message-ID: I don’t mean to be negative about it. I’m sold on the motivation. It just seems quite a deep-seated change (e.g. affecting transformations in Core because mutable constructors have identity) and I don’t have that satisfying “aha” feeling when all the pieces mesh together – something that is a hallmark of Haskell. I wish I could propose a constructive alternative. It’s tiresome when people just object on somewhat vague grounds but don’t offer any concrete alternatives. Simon From: ghc-steering-committee [mailto:ghc-steering-committee-bounces at haskell.org] On Behalf Of Simon Marlow Sent: 01 March 2018 08:49 To: Joachim Breitner Cc: ghc-steering-committee at haskell.org Subject: Re: [ghc-steering-committee] Please review: Mutable constructor fields, Shepherd: Ryan Newton Simon has provided a detailed review (thanks!) so I think we'll need some time to digest those comments and suggestions and modify the proposal. In light of that shall we put the proposal back into the discussion phase for now? Cheers Simon On 1 March 2018 at 05:17, Joachim Breitner > wrote: Hi, Am Freitag, den 23.02.2018, 15:22 -0500 schrieb Ryan Newton: > Ok, I'm not hearing any strong objections and over the long course of > discussion in various venues, reactions have been mostly positive. > Since committee discussion here has died down, I move to go ahead and > accept this proposal if there are no further objections. it has been quiet here, but I see new activity on https://github.com/ghc-proposals/ghc-proposals/pull/8 Is this a sign that the proposal is not yet as polished as would hope for? Joachim -- Joachim “nomeata” Breitner mail at joachim-breitner.de https://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 ben at well-typed.com Fri Mar 2 17:02:44 2018 From: ben at well-typed.com (Ben Gamari) Date: Fri, 02 Mar 2018 12:02:44 -0500 Subject: [ghc-steering-committee] Plugin recompilation avoidance In-Reply-To: <87fu5ost72.fsf@smart-cactus.org> References: <87fu5ost72.fsf@smart-cactus.org> Message-ID: <87woyupg0h.fsf@smart-cactus.org> Ben Gamari writes: > Hi everyone, > > I'm writing you in reference to GHC Proposal #108 [1], which introduces > a mechanism allowing plugins greater control over GHC's recompilation > behavior. > As there has been no response I will assume that there are no objections to the proposal as it stands. Cheers, - Ben -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 487 bytes Desc: not available URL: From ben at well-typed.com Fri Mar 2 17:05:20 2018 From: ben at well-typed.com (Ben Gamari) Date: Fri, 02 Mar 2018 12:05:20 -0500 Subject: [ghc-steering-committee] Plugin recompilation avoidance interface (#108) In-Reply-To: <87a7w4uzt8.fsf@smart-cactus.org> References: <87a7w4uzt8.fsf@smart-cactus.org> Message-ID: <87tvtypfw2.fsf@smart-cactus.org> Ben Gamari writes: > Hello everyone, > > I have been assigned as the shepard for proposal #108. This proposes a > change in GHC's plugin interface allowing plugins greater control over > recompilation, significantly improving compilation times for projects > relying on compiler plugins. > > > Summary: > > The proposal suggests that the existing fields of the `ghc` package's > Plugin.Plugin type be wrapped with a type capturing a function computing > the plugin's recompilation desired behavior, > > data PluginRecompile = ForceRecompile > | NoForceRecompile > | MaybeRecompile Fingerprint > > GHC can then use this recompilation information to decide whether > evaluating the plugin (and consequently invalidating any existing > compilation artifacts) is necessary. > > > Opinion & recommendation: > > The proposal addresses a long-standing limitation (#7414) of the GHC > plugin interface which has become increasingly visible to users in > recent years. While the particular approach proposed breaks existing > plugin users, it is expressive enough to allow GHC to perform more > aggressive recompilation avoidance in the future [1]. Moreover, the > smart constructors proposed should make for a reasonably smooth > migration path. > > Given that the plugins appears to have buy-in from a few notable plugin > authors, I recommend that we accept this proposal. > I've pinged a number of prominent plugin authors and heard no reply. Therefore, I would again recommend that we accept. Cheers, - Ben -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 487 bytes Desc: not available URL: From iavor.diatchki at gmail.com Fri Mar 2 17:49:54 2018 From: iavor.diatchki at gmail.com (Iavor Diatchki) Date: Fri, 02 Mar 2018 17:49:54 +0000 Subject: [ghc-steering-committee] Plugin recompilation avoidance interface (#108) In-Reply-To: <87tvtypfw2.fsf@smart-cactus.org> References: <87a7w4uzt8.fsf@smart-cactus.org> <87tvtypfw2.fsf@smart-cactus.org> Message-ID: Hello, I've been really busy at work so I haven't had time to look at this in detail, but I think the proposal address an important problem that I've actually encountered, so I think it is great that we are doing something about it, so I am +1 in principle. -Iavor On Fri, Mar 2, 2018 at 9:05 AM Ben Gamari wrote: > Ben Gamari writes: > > > Hello everyone, > > > > I have been assigned as the shepard for proposal #108. This proposes a > > change in GHC's plugin interface allowing plugins greater control over > > recompilation, significantly improving compilation times for projects > > relying on compiler plugins. > > > > > > Summary: > > > > The proposal suggests that the existing fields of the `ghc` package's > > Plugin.Plugin type be wrapped with a type capturing a function computing > > the plugin's recompilation desired behavior, > > > > data PluginRecompile = ForceRecompile > > | NoForceRecompile > > | MaybeRecompile Fingerprint > > > > GHC can then use this recompilation information to decide whether > > evaluating the plugin (and consequently invalidating any existing > > compilation artifacts) is necessary. > > > > > > Opinion & recommendation: > > > > The proposal addresses a long-standing limitation (#7414) of the GHC > > plugin interface which has become increasingly visible to users in > > recent years. While the particular approach proposed breaks existing > > plugin users, it is expressive enough to allow GHC to perform more > > aggressive recompilation avoidance in the future [1]. Moreover, the > > smart constructors proposed should make for a reasonably smooth > > migration path. > > > > Given that the plugins appears to have buy-in from a few notable plugin > > authors, I recommend that we accept this proposal. > > > I've pinged a number of prominent plugin authors and heard no reply. > Therefore, I would again recommend that we accept. > > Cheers, > > - Ben > _______________________________________________ > 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 Sat Mar 3 13:43:24 2018 From: mail at joachim-breitner.de (Joachim Breitner) Date: Sat, 03 Mar 2018 08:43:24 -0500 Subject: [ghc-steering-committee] Please Review: Or patterns, Shepherd: Manuel Message-ID: <1520084604.1208.2.camel@joachim-breitner.de> Dear Committee, this is your secretary speaking: Or patterns were proposed by Ömer https://github.com/ghc-proposals/ghc-proposals/pull/43 I propose Manuel Chakravarty as the shepherd. Manuel, please reach consensus as described in https://github.com/ghc-proposals/ghc-proposals#committee-process I suggest you make a recommendation, in a new e-mail thread, about the decision, maybe point out debatable points, and assume that anyone who stays quiet agrees with you. Thanks, -- Joachim Breitner mail at joachim-breitner.de http://www.joachim-breitner.de/ -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 833 bytes Desc: This is a digitally signed message part URL: From rrnewton at indiana.edu Sat Mar 3 23:14:19 2018 From: rrnewton at indiana.edu (Ryan Newton) Date: Sat, 3 Mar 2018 18:14:19 -0500 Subject: [ghc-steering-committee] Please review: Mutable constructor fields, Shepherd: Ryan Newton In-Reply-To: References: <1500034660.7133.5.camel@joachim-breitner.de> <33016754-2802-47E0-87B3-0BBD80C12FFE@cs.brynmawr.edu> <1519881466.24339.4.camel@joachim-breitner.de> Message-ID: I'm certainly fine with going back to discussion. Simon PJ, much of your review was improvements/edits, and after those are incorporated, which are the highest priority, deal-breaker issues for you? In particular, the requirement to use reallyUnsafePtrEq# received some subsequent discussion. If we require at least one mutable field for a constructor to have physical equality, then reallyUnsafePtrEq# can be avoided both in derived or handwritten equality functions. Does that improve your assessment? Best, -Ryan On Thu, Mar 1, 2018 at 3:48 AM, Simon Marlow wrote: > Simon has provided a detailed review (thanks!) so I think we'll need some > time to digest those comments and suggestions and modify the proposal. In > light of that shall we put the proposal back into the discussion phase for > now? > > Cheers > Simon > > On 1 March 2018 at 05:17, Joachim Breitner > wrote: > >> Hi, >> >> Am Freitag, den 23.02.2018, 15:22 -0500 schrieb Ryan Newton: >> > Ok, I'm not hearing any strong objections and over the long course of >> > discussion in various venues, reactions have been mostly positive. >> > Since committee discussion here has died down, I move to go ahead and >> > accept this proposal if there are no further objections. >> >> it has been quiet here, but I see new activity on >> https://github.com/ghc-proposals/ghc-proposals/pull/8 >> >> Is this a sign that the proposal is not yet as polished as would hope >> for? >> >> Joachim >> >> -- >> Joachim “nomeata” Breitner >> mail at joachim-breitner.de >> https://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 marlowsd at gmail.com Mon Mar 5 08:57:48 2018 From: marlowsd at gmail.com (Simon Marlow) Date: Mon, 5 Mar 2018 08:57:48 +0000 Subject: [ghc-steering-committee] Plugin recompilation avoidance interface (#108) In-Reply-To: References: <87a7w4uzt8.fsf@smart-cactus.org> <87tvtypfw2.fsf@smart-cactus.org> Message-ID: Also +1 from me in principle - with the caveat that I haven't written any plugins, but I am quite familiar with how recompilation avoidance works. It's an important issue to address, and I didn't spot any obvious problems with the design. Cheers Simon On 2 March 2018 at 17:49, Iavor Diatchki wrote: > Hello, > > I've been really busy at work so I haven't had time to look at this in > detail, but I think the proposal address an important problem that I've > actually encountered, so I think it is great that we are doing something > about it, so I am +1 in principle. > > -Iavor > > On Fri, Mar 2, 2018 at 9:05 AM Ben Gamari wrote: > >> Ben Gamari writes: >> >> > Hello everyone, >> > >> > I have been assigned as the shepard for proposal #108. This proposes a >> > change in GHC's plugin interface allowing plugins greater control over >> > recompilation, significantly improving compilation times for projects >> > relying on compiler plugins. >> > >> > >> > Summary: >> > >> > The proposal suggests that the existing fields of the `ghc` package's >> > Plugin.Plugin type be wrapped with a type capturing a function computing >> > the plugin's recompilation desired behavior, >> > >> > data PluginRecompile = ForceRecompile >> > | NoForceRecompile >> > | MaybeRecompile Fingerprint >> > >> > GHC can then use this recompilation information to decide whether >> > evaluating the plugin (and consequently invalidating any existing >> > compilation artifacts) is necessary. >> > >> > >> > Opinion & recommendation: >> > >> > The proposal addresses a long-standing limitation (#7414) of the GHC >> > plugin interface which has become increasingly visible to users in >> > recent years. While the particular approach proposed breaks existing >> > plugin users, it is expressive enough to allow GHC to perform more >> > aggressive recompilation avoidance in the future [1]. Moreover, the >> > smart constructors proposed should make for a reasonably smooth >> > migration path. >> > >> > Given that the plugins appears to have buy-in from a few notable plugin >> > authors, I recommend that we accept this proposal. >> > >> I've pinged a number of prominent plugin authors and heard no reply. >> Therefore, I would again recommend that we accept. >> >> Cheers, >> >> - Ben >> _______________________________________________ >> 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 Mar 5 09:17:33 2018 From: simonpj at microsoft.com (Simon Peyton Jones) Date: Mon, 5 Mar 2018 09:17:33 +0000 Subject: [ghc-steering-committee] Please review: Mutable constructor fields, Shepherd: Ryan Newton In-Reply-To: References: <1500034660.7133.5.camel@joachim-breitner.de> <33016754-2802-47E0-87B3-0BBD80C12FFE@cs.brynmawr.edu> <1519881466.24339.4.camel@joachim-breitner.de> Message-ID: which are the highest priority, deal-breaker issues for you? As I say, I’m uncomfortable, but since I can’t identify anything solidly wrong with it, I don’t want to stand in the way. Once we have a full implementation, and can see the impacts on the codebase, we may be in a better position to judge. (This is true of every proposal whose impacts across the compiler are hard to predict, not just this one.) If we require at least one mutable field for a constructor to have physical equality, then reallyUnsafePtrEq# can be avoided both in derived or handwritten equality functions Well, of course you need at least one mutable field! But having got it, how do we get rid of the unsafe-ptr-eq? Perhaps the thing to do is to update the proposal to whatever the new idea is? Simon From: Ryan Newton [mailto:rrnewton at indiana.edu] Sent: 03 March 2018 23:14 To: Simon Marlow ; Simon Peyton Jones Cc: Joachim Breitner ; ghc-steering-committee at haskell.org Subject: Re: [ghc-steering-committee] Please review: Mutable constructor fields, Shepherd: Ryan Newton I'm certainly fine with going back to discussion. Simon PJ, much of your review was improvements/edits, and after those are incorporated, which are the highest priority, deal-breaker issues for you? In particular, the requirement to use reallyUnsafePtrEq# received some subsequent discussion. If we require at least one mutable field for a constructor to have physical equality, then reallyUnsafePtrEq# can be avoided both in derived or handwritten equality functions. Does that improve your assessment? Best, -Ryan On Thu, Mar 1, 2018 at 3:48 AM, Simon Marlow > wrote: Simon has provided a detailed review (thanks!) so I think we'll need some time to digest those comments and suggestions and modify the proposal. In light of that shall we put the proposal back into the discussion phase for now? Cheers Simon On 1 March 2018 at 05:17, Joachim Breitner > wrote: Hi, Am Freitag, den 23.02.2018, 15:22 -0500 schrieb Ryan Newton: > Ok, I'm not hearing any strong objections and over the long course of > discussion in various venues, reactions have been mostly positive. > Since committee discussion here has died down, I move to go ahead and > accept this proposal if there are no further objections. it has been quiet here, but I see new activity on https://github.com/ghc-proposals/ghc-proposals/pull/8 Is this a sign that the proposal is not yet as polished as would hope for? Joachim -- Joachim “nomeata” Breitner mail at joachim-breitner.de https://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 mail at joachim-breitner.de Mon Mar 5 14:14:46 2018 From: mail at joachim-breitner.de (Joachim Breitner) Date: Mon, 05 Mar 2018 09:14:46 -0500 Subject: [ghc-steering-committee] Plugin recompilation avoidance interface (#108) In-Reply-To: References: <87a7w4uzt8.fsf@smart-cactus.org> <87tvtypfw2.fsf@smart-cactus.org> Message-ID: <1520259286.1311.10.camel@joachim-breitner.de> Hi, we are all in agreement that we want plugins the ability to avoid recompilation. The open question is: Should this be on a per module basis? Or a per module-and-pass bases? The former has a simpler and backward-compatible API, the latter sets the stage for some potential future where the compiler might typecheck a program, but then abort and not code generate. … seriously, I still don’t see how that future can be. Can someone please give a concrete example of circumstances where that might happen? Ben hints at sub-module granularity, but that slices it orthogonal to the current proposal. He also write > Lumping together all of the recompilation checks into a > single hash would expose a relatively ugly facet of GHC's implementation > to plugin authors and force authors to tie together logic from > conceptually-distinct compilation phases. but that is also not quite true. Note that the hash is not generated _during_ the passes, but needs to be calculated before. The type signature of the recalculation check, namely pluginRecompile :: [CommandLineOption] -> IfG PluginRecompile clearly indicates that this is a per-module check (otherwise, you’d see an ModGuts input, or such). And even if, in the future, we have ability to provide a finer grained mechanism, we can add the necessary functions _then_ when we know how it looks. Cheers, Joachim Am Montag, den 05.03.2018, 08:57 +0000 schrieb Simon Marlow: > Also +1 from me in principle - with the caveat that I haven't written any plugins, but I am quite familiar with how recompilation avoidance works. It's an important issue to address, and I didn't spot any obvious problems with the design. > > Cheers > Simon > > On 2 March 2018 at 17:49, Iavor Diatchki wrote: > > Hello, > > > > I've been really busy at work so I haven't had time to look at this in detail, but I think the proposal address an important problem that I've actually encountered, so I think it is great that we are doing something about it, so I am +1 in principle. > > > > -Iavor > > > > On Fri, Mar 2, 2018 at 9:05 AM Ben Gamari wrote: > > > Ben Gamari writes: > > > > > > > Hello everyone, > > > > > > > > I have been assigned as the shepard for proposal #108. This proposes a > > > > change in GHC's plugin interface allowing plugins greater control over > > > > recompilation, significantly improving compilation times for projects > > > > relying on compiler plugins. > > > > > > > > > > > > Summary: > > > > > > > > The proposal suggests that the existing fields of the `ghc` package's > > > > Plugin.Plugin type be wrapped with a type capturing a function computing > > > > the plugin's recompilation desired behavior, > > > > > > > > data PluginRecompile = ForceRecompile > > > > | NoForceRecompile > > > > | MaybeRecompile Fingerprint > > > > > > > > GHC can then use this recompilation information to decide whether > > > > evaluating the plugin (and consequently invalidating any existing > > > > compilation artifacts) is necessary. > > > > > > > > > > > > Opinion & recommendation: > > > > > > > > The proposal addresses a long-standing limitation (#7414) of the GHC > > > > plugin interface which has become increasingly visible to users in > > > > recent years. While the particular approach proposed breaks existing > > > > plugin users, it is expressive enough to allow GHC to perform more > > > > aggressive recompilation avoidance in the future [1]. Moreover, the > > > > smart constructors proposed should make for a reasonably smooth > > > > migration path. > > > > > > > > Given that the plugins appears to have buy-in from a few notable plugin > > > > authors, I recommend that we accept this proposal. > > > > > > > I've pinged a number of prominent plugin authors and heard no reply. > > > Therefore, I would again recommend that we accept. > > > > > > Cheers, > > > > > > - Ben > > > _______________________________________________ > > > 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 -- Joachim Breitner mail at joachim-breitner.de http://www.joachim-breitner.de/ -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 833 bytes Desc: This is a digitally signed message part URL: From rrnewton at indiana.edu Mon Mar 5 15:42:20 2018 From: rrnewton at indiana.edu (Ryan Newton) Date: Mon, 5 Mar 2018 10:42:20 -0500 Subject: [ghc-steering-committee] Please review: Mutable constructor fields, Shepherd: Ryan Newton In-Reply-To: References: <1500034660.7133.5.camel@joachim-breitner.de> <33016754-2802-47E0-87B3-0BBD80C12FFE@cs.brynmawr.edu> <1519881466.24339.4.camel@joachim-breitner.de> Message-ID: Dear Simon, > If we require at least one mutable field for a constructor to have > physical equality, then reallyUnsafePtrEq# can be avoided both in derived > or handwritten equality functions > > > > Well, of course you need at least one mutable field! But having got it, > how do we get rid of the unsafe-ptr-eq? > FYI, the proposal as written now also allows constructors with no mutable fields but still offering O(1) physical identity: data T where MkT :: [Int] -> IO T deriving Eq But if this is disallowed, and we have *at least one* mutable field... data T where MkT :: mutable [Int] -> IO T Then the simple observation is that we no longer need to use reallyUnsafePtrEq on two MkT constructors themselves, rather we can simply use Ref# equality on any pair of matching fields: eq (MkT a) (MkT b) = refEq a b Ref# equality is just a one-word pointer comparison of course, but unlike reallyUnsafePtrEq, it's always safe. > Perhaps the thing to do is to update the proposal to whatever the new idea > is? > Yes, indeed! Let's. Best, -Ryan > > > Simon > > > > *From:* Ryan Newton [mailto:rrnewton at indiana.edu] > *Sent:* 03 March 2018 23:14 > *To:* Simon Marlow ; Simon Peyton Jones < > simonpj at microsoft.com> > *Cc:* Joachim Breitner ; > ghc-steering-committee at haskell.org > *Subject:* Re: [ghc-steering-committee] Please review: Mutable > constructor fields, Shepherd: Ryan Newton > > > > I'm certainly fine with going back to discussion. > > > > Simon PJ, much of your review was improvements/edits, and after those are > incorporated, which are the highest priority, deal-breaker issues for you? > > > > In particular, the requirement to use reallyUnsafePtrEq# received some > subsequent discussion. If we require at least one mutable field for a > constructor to have physical equality, then reallyUnsafePtrEq# can be > avoided both in derived or handwritten equality functions. Does that > improve your assessment? > > > > Best, > > -Ryan > > > > > > > > On Thu, Mar 1, 2018 at 3:48 AM, Simon Marlow wrote: > > Simon has provided a detailed review (thanks!) so I think we'll need some > time to digest those comments and suggestions and modify the proposal. In > light of that shall we put the proposal back into the discussion phase for > now? > > Cheers > > Simon > > > > On 1 March 2018 at 05:17, Joachim Breitner > wrote: > > Hi, > > Am Freitag, den 23.02.2018, 15:22 -0500 schrieb Ryan Newton: > > Ok, I'm not hearing any strong objections and over the long course of > > discussion in various venues, reactions have been mostly positive. > > Since committee discussion here has died down, I move to go ahead and > > accept this proposal if there are no further objections. > > it has been quiet here, but I see new activity on > https://github.com/ghc-proposals/ghc-proposals/pull/8 > > > Is this a sign that the proposal is not yet as polished as would hope > for? > > Joachim > > -- > Joachim “nomeata” Breitner > mail at joachim-breitner.de > https://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 Mar 5 16:18:18 2018 From: simonpj at microsoft.com (Simon Peyton Jones) Date: Mon, 5 Mar 2018 16:18:18 +0000 Subject: [ghc-steering-committee] Please review: Mutable constructor fields, Shepherd: Ryan Newton In-Reply-To: References: <1500034660.7133.5.camel@joachim-breitner.de> <33016754-2802-47E0-87B3-0BBD80C12FFE@cs.brynmawr.edu> <1519881466.24339.4.camel@joachim-breitner.de> Message-ID: Ref# equality is just a one-word pointer comparison of course, but unlike reallyUnsafePtrEq, it's always safe. I haven’t checked, but there is presumably a new primop eqRef# :: Ref# a -> Ref# a -> Bool? Or (hmm) maybe eqRef# :: Ref# a -> Ref# b -> Maybe (a ~ b) a bit like equality on TypeRep. NNTR: just a suggestion for the proposal. Simon From: Ryan Newton [mailto:rrnewton at indiana.edu] Sent: 05 March 2018 15:42 To: Simon Peyton Jones Cc: Simon Marlow ; Joachim Breitner ; ghc-steering-committee at haskell.org Subject: Re: [ghc-steering-committee] Please review: Mutable constructor fields, Shepherd: Ryan Newton Dear Simon, If we require at least one mutable field for a constructor to have physical equality, then reallyUnsafePtrEq# can be avoided both in derived or handwritten equality functions Well, of course you need at least one mutable field! But having got it, how do we get rid of the unsafe-ptr-eq? FYI, the proposal as written now also allows constructors with no mutable fields but still offering O(1) physical identity: data T where MkT :: [Int] -> IO T deriving Eq But if this is disallowed, and we have at least one mutable field... data T where MkT :: mutable [Int] -> IO T Then the simple observation is that we no longer need to use reallyUnsafePtrEq on two MkT constructors themselves, rather we can simply use Ref# equality on any pair of matching fields: eq (MkT a) (MkT b) = refEq a b Ref# equality is just a one-word pointer comparison of course, but unlike reallyUnsafePtrEq, it's always safe. Perhaps the thing to do is to update the proposal to whatever the new idea is? Yes, indeed! Let's. Best, -Ryan Simon From: Ryan Newton [mailto:rrnewton at indiana.edu] Sent: 03 March 2018 23:14 To: Simon Marlow >; Simon Peyton Jones > Cc: Joachim Breitner >; ghc-steering-committee at haskell.org Subject: Re: [ghc-steering-committee] Please review: Mutable constructor fields, Shepherd: Ryan Newton I'm certainly fine with going back to discussion. Simon PJ, much of your review was improvements/edits, and after those are incorporated, which are the highest priority, deal-breaker issues for you? In particular, the requirement to use reallyUnsafePtrEq# received some subsequent discussion. If we require at least one mutable field for a constructor to have physical equality, then reallyUnsafePtrEq# can be avoided both in derived or handwritten equality functions. Does that improve your assessment? Best, -Ryan On Thu, Mar 1, 2018 at 3:48 AM, Simon Marlow > wrote: Simon has provided a detailed review (thanks!) so I think we'll need some time to digest those comments and suggestions and modify the proposal. In light of that shall we put the proposal back into the discussion phase for now? Cheers Simon On 1 March 2018 at 05:17, Joachim Breitner > wrote: Hi, Am Freitag, den 23.02.2018, 15:22 -0500 schrieb Ryan Newton: > Ok, I'm not hearing any strong objections and over the long course of > discussion in various venues, reactions have been mostly positive. > Since committee discussion here has died down, I move to go ahead and > accept this proposal if there are no further objections. it has been quiet here, but I see new activity on https://github.com/ghc-proposals/ghc-proposals/pull/8 Is this a sign that the proposal is not yet as polished as would hope for? Joachim -- Joachim “nomeata” Breitner mail at joachim-breitner.de https://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 ben at well-typed.com Sun Mar 11 20:31:52 2018 From: ben at well-typed.com (Ben Gamari) Date: Sun, 11 Mar 2018 16:31:52 -0400 Subject: [ghc-steering-committee] Plugin recompilation avoidance interface (#108) In-Reply-To: <1520259286.1311.10.camel@joachim-breitner.de> References: <87a7w4uzt8.fsf@smart-cactus.org> <87tvtypfw2.fsf@smart-cactus.org> <1520259286.1311.10.camel@joachim-breitner.de> Message-ID: <87ina2z74g.fsf@smart-cactus.org> Joachim Breitner writes: > Hi, > Sorry for the late response; this was buried in my inbox. > we are all in agreement that we want plugins the ability to avoid > recompilation. The open question is: Should this be on a per module > basis? Or a per module-and-pass bases? > > The former has a simpler and backward-compatible API, the latter sets > the stage for some potential future where the compiler might typecheck > a program, but then abort and not code generate. > > … seriously, I still don’t see how that future can be. Can someone > please give a concrete example of circumstances where that might > happen? > > Ben hints at sub-module granularity, but that slices it orthogonal to > the current proposal. He also write > >> Lumping together all of the recompilation checks into a >> single hash would expose a relatively ugly facet of GHC's implementation >> to plugin authors and force authors to tie together logic from >> conceptually-distinct compilation phases. > > but that is also not quite true. Note that the hash is not generated > _during_ the passes, but needs to be calculated before. The type > signature of the recalculation check, namely > > pluginRecompile :: [CommandLineOption] -> IfG PluginRecompile > > clearly indicates that this is a per-module check (otherwise, you’d see > an ModGuts input, or such). > > > And even if, in the future, we have ability to provide a finer grained > mechanism, we can add the necessary functions _then_ when we know how > it looks. > Your argument is pretty compelling. I'll admit that part of my dislike of the the simple approach that you advocate is purely aesthetic; it just feels terribly ad-hoc. That being said, you do raise a valid point that we really don't know enough to be able to say what a more precise interface would look like. Moreover, there is something to be said for the nice backwards-compatibility story that the simple approach allows. I would be fine accepting the simple approach. Either way, I think we should move this proposal forward to unblock our contributor. Cheers, - Ben -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 487 bytes Desc: not available URL: From mail at joachim-breitner.de Sun Mar 18 21:49:23 2018 From: mail at joachim-breitner.de (Joachim Breitner) Date: Sun, 18 Mar 2018 17:49:23 -0400 Subject: [ghc-steering-committee] As patterns in pattern synonyms (#94), Recommendation: accept In-Reply-To: References: <1519741198.1113.11.camel@joachim-breitner.de> Message-ID: <1521409763.6087.13.camel@joachim-breitner.de> Hi, I declare consensus; accepted, Joachim Am Mittwoch, den 28.02.2018, 09:25 +0000 schrieb Simon Marlow: > Looks good to me. > > On 27 February 2018 at 14:19, Joachim Breitner wrote: > > Dear Committee, > > > > this is your secretary speaking: > > > > As patterns in pattern synonyms, by Richard. > > https://github.com/ghc-proposals/ghc-proposals/pull/94 > > rendered at > > https://github.com/ghc-proposals/ghc-proposals/blob/as-pattern-synonyms/AsPatternSynonyms.rst > > > > I’ll shepherd that myself. > > > > This proposal removes restrictions on what can be used in > > unidirectional pattern synonyms, where @-pattern were previously > > disallowed. The restriction would make sense if patterns synonyms are > > macros, but they are not. I am always in favor of removing special > > cases and restrictions, so I recommend to accept this proposal. > > > > Thanks, > > 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 > > > > _______________________________________________ > ghc-steering-committee mailing list > ghc-steering-committee at haskell.org > https://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-steering-committee -- Joachim Breitner mail at joachim-breitner.de http://www.joachim-breitner.de/ -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 833 bytes Desc: This is a digitally signed message part URL: From mail at joachim-breitner.de Sun Mar 18 21:56:10 2018 From: mail at joachim-breitner.de (Joachim Breitner) Date: Sun, 18 Mar 2018 17:56:10 -0400 Subject: [ghc-steering-committee] Status Message-ID: <1521410170.6087.19.camel@joachim-breitner.de> Hi, I hope you all survived the ICFP deadline well, and surely you are now all eager to work off the pretty long list of proposals that are before us. Since the last status update, we * were asked to review these proposals: - kind and type vars in forall (Shepherd: SPJ) - Source Plugins (Shepherd: Chris Allen) - Constraint vs. Type (Shepherd: SPJ) - Type-level type app (Shepherd: Richard) - kind!! (Shepherd: Manuel) - as-patterns (Shepherd: me) - scoped type vars (Shepherd: Roman) - or-patterns (Shepherd: Manuel) * got a recommendation from shepherds about: - Int8/Word8 (accept) - DH quantifiers (accept) - Type-level type app (accept) - Constraint vs. Type (accept) - as-patterns (accept) * decided about the following proposals - unlifted newtypes (accept) - Int8/Word8 (accept) - type level app (accept) - as-patterns (accept) Plenty of work to do, as we currently have to act on the following 12 proposals! Plugin recompilation API https://github.com/ghc-proposals/ghc-proposals/pull/108 Shepherd: Ben, recommends acceptance Status: Ongoing discussion, with me solitarily holding up the process with criticism Source Plugins https://github.com/ghc-proposals/ghc-proposals/pull/107 Shepherd: Chris Allen Status: Waiting for Allen’s recommendation kind and type vars https://github.com/ghc-proposals/ghc-proposals/pull/103 Shepherd: SPJ Status: Waiting for Simon to make a recommendation Dependent Haskell quantifier syntax https://github.com/ghc-proposals/ghc-proposals/pull/102 Shepherd: Joachim, recommends acceptance Status: Reservations from SPJ and Iavor, no consensus emerging so far. Binding existential variables https://github.com/ghc-proposals/ghc-proposals/pull/96 Shepherd: Roman Status: Waiting for Roman to make a recommendation Embrace Type-In-Type https://github.com/ghc-proposals/ghc-proposals/pull/83 Shepherd: Iavor Status: Ongoing discussion, mostly about the fate of * Visible dependent quantification (TL;DR: forall k -> k -> *) https://github.com/ghc-proposals/ghc-proposals/pull/81 Shepherd: Roman Leshchinskiy Status: Unclear. Blocked on #102? :kind!! https://github.com/ghc-proposals/ghc-proposals/pull/79 Shepherd: Manuel Status: Waiting for Manuel to make a recommendation Or-Patterns https://github.com/ghc-proposals/ghc-proposals/pull/43 Shepherd: Manuel Status: Waiting for Manuel to make a recommendation Constraint vs. Type https://github.com/ghc-proposals/ghc-proposals/pull/32 Shepherd: Simon PJS (proposed acceptance) Status: Simon’s proposal was met with silence. Ergo accept? Mutable constructor fields https://github.com/ghc-proposals/ghc-proposals/pull/8 Shepherd: Ryan Newton Status: There was more discussion. Does this need to go back to the discussion phase? Cheers, Joachim -- Joachim Breitner mail at joachim-breitner.de http://www.joachim-breitner.de/ -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 833 bytes Desc: This is a digitally signed message part URL: From chak at justtesting.org Wed Mar 21 02:42:45 2018 From: chak at justtesting.org (Manuel M T Chakravarty) Date: Wed, 21 Mar 2018 13:42:45 +1100 Subject: [ghc-steering-committee] =?utf-8?q?Proposal_=2379_=22Add_a_=3Akin?= =?utf-8?q?d!!_command_to_ghci=22_=E2=80=94_propose_yes?= Message-ID: <1A21C65F-1761-47F1-B922-E70BFFE12CAB@justtesting.org> We need to decide on the Proposal #79 ”Add a :kind!! command to ghci, to expand type families and type synonyms”: (rendered) https://github.com/alpmestan/ghc-proposals/blob/master/proposals/0000-kind-bang-bang.rst (discussion) https://github.com/ghc-proposals/ghc-proposals/pull/79 I agree that this is useful functionality and it is a simple change to GHCi. There has been some discussion about the naming of this command, but TBH I didn’t find any of the alternatives more convincing than ”:kind!!”, so I’d suggest to stick with that. I favour accepting this proposal. Are there any dissenting opinions? Cheers, Manuel From rae at cs.brynmawr.edu Wed Mar 21 02:53:49 2018 From: rae at cs.brynmawr.edu (Richard Eisenberg) Date: Tue, 20 Mar 2018 22:53:49 -0400 Subject: [ghc-steering-committee] =?utf-8?q?Proposal_=2379_=22Add_a_=3Akin?= =?utf-8?q?d!!_command_to_ghci=22_=E2=80=94_propose_yes?= In-Reply-To: <1A21C65F-1761-47F1-B922-E70BFFE12CAB@justtesting.org> References: <1A21C65F-1761-47F1-B922-E70BFFE12CAB@justtesting.org> Message-ID: I think this is useful, but I strongly dislike :kind!!. Currently: > :type gives the type of an expression, without evaluating it > :kind gives the kind of a type, without evaluating it > evaluates an expression Obviously, we can't have > evaluates a type because that's terribly ambiguous. On the thread, I proposed :eval-type, which got a less-than-lukewarm response. But I'll propose that here, regardless. Really, anything is better than :kind!! for me. (And I think we should remove :kind! too, and use a system like with have with :type +v and :type +d to have an evaluate-this-type command, with options.) Richard > On Mar 20, 2018, at 10:42 PM, Manuel M T Chakravarty wrote: > > We need to decide on the Proposal #79 ”Add a :kind!! command to ghci, to expand type families and type synonyms”: > > (rendered) https://github.com/alpmestan/ghc-proposals/blob/master/proposals/0000-kind-bang-bang.rst > (discussion) https://github.com/ghc-proposals/ghc-proposals/pull/79 > > I agree that this is useful functionality and it is a simple change to GHCi. There has been some discussion about the naming of this command, but TBH I didn’t find any of the alternatives more convincing than ”:kind!!”, so I’d suggest to stick with that. > > I favour accepting this proposal. Are there any dissenting opinions? > > Cheers, > Manuel > > _______________________________________________ > ghc-steering-committee mailing list > ghc-steering-committee at haskell.org > https://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-steering-committee From mail at joachim-breitner.de Wed Mar 21 18:25:01 2018 From: mail at joachim-breitner.de (Joachim Breitner) Date: Wed, 21 Mar 2018 14:25:01 -0400 Subject: [ghc-steering-committee] =?utf-8?q?Proposal_=2379_=22Add_a_=3Akin?= =?utf-8?q?d!!_command_to_ghci=22_=E2=80=94_propose_yes?= In-Reply-To: References: <1A21C65F-1761-47F1-B922-E70BFFE12CAB@justtesting.org> Message-ID: <1521656701.3980.5.camel@joachim-breitner.de> Hi, I agree with Richard that we can give some care to coming up with good command names. Given that we have precedence of +v and +d flags for :type, maybe we want the same for :kind. :kind gives the kind of a type, without evaluating it :kind +tf gives the kind of a type, evaluating type families :kind +s gives the kind of a type, evaluating synonyms :kind +tf +s is of course allowed. But it is weird to call it :kind when the focus here is the type… How about we special case the syntax :type _ :: Foo to work without having to set -fdefer-typed-holes, indicating “I don’t care about the value; show me the type Foo”. We can then add additional flags to :type to control the type evaluation behavior more precisely. Cheers, Joachim Am Dienstag, den 20.03.2018, 22:53 -0400 schrieb Richard Eisenberg: > I think this is useful, but I strongly dislike :kind!!. > > Currently: > > > :type gives the type of an expression, without evaluating it > > :kind gives the kind of a type, without evaluating it > > evaluates an expression > > Obviously, we can't have > > > evaluates a type > > because that's terribly ambiguous. > > On the thread, I proposed :eval-type, which got a less-than-lukewarm > response. But I'll propose that here, regardless. Really, anything is > better than :kind!! for me. (And I think we should remove :kind! too, > and use a system like with have with :type +v and :type +d to have an > evaluate-this-type command, with options.) > > Richard > > > On Mar 20, 2018, at 10:42 PM, Manuel M T Chakravarty wrote: > > > > We need to decide on the Proposal #79 ”Add a :kind!! command to ghci, to expand type families and type synonyms”: > > > > (rendered) https://github.com/alpmestan/ghc-proposals/blob/master/proposals/0000-kind-bang-bang.rst > > (discussion) https://github.com/ghc-proposals/ghc-proposals/pull/79 > > > > I agree that this is useful functionality and it is a simple change to GHCi. There has been some discussion about the naming of this command, but TBH I didn’t find any of the alternatives more convincing than ”:kind!!”, so I’d suggest to stick with that. > > > > I favour accepting this proposal. Are there any dissenting opinions? > > > > Cheers, > > Manuel > > > > _______________________________________________ > > 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 -- Joachim Breitner mail at joachim-breitner.de http://www.joachim-breitner.de/ -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 833 bytes Desc: This is a digitally signed message part URL: From rae at cs.brynmawr.edu Wed Mar 21 18:45:57 2018 From: rae at cs.brynmawr.edu (Richard Eisenberg) Date: Wed, 21 Mar 2018 14:45:57 -0400 Subject: [ghc-steering-committee] =?utf-8?q?Proposal_=2379_=22Add_a_=3Akin?= =?utf-8?q?d!!_command_to_ghci=22_=E2=80=94_propose_yes?= In-Reply-To: <1521656701.3980.5.camel@joachim-breitner.de> References: <1A21C65F-1761-47F1-B922-E70BFFE12CAB@justtesting.org> <1521656701.3980.5.camel@joachim-breitner.de> Message-ID: > On Mar 21, 2018, at 2:25 PM, Joachim Breitner wrote: > > How about we special case the syntax > > :type _ :: Foo > I really liked this for a moment, but then I realized it doesn't work if you want to reduce a type that isn't of kind Type. But maybe you're onto something here. What about having the following set of options for :type: 1. +v means to print the type of the thing exactly as-is, without any funny business 2. +d means to default the type 3. +t means that you're asking for the type of a type, instead of the type of an expression 4. +f means to evaluate any type families 5. +s means to expand any type synonyms +v is incompatible with +d, +f, and +s. Otherwise, I think these mix nicely. :kind becomes a synonym for :type +t and :kind! becomes a synonym for :type +t +f. Note that users can define their own synonyms through :def. Richard From simonpj at microsoft.com Thu Mar 22 09:00:12 2018 From: simonpj at microsoft.com (Simon Peyton Jones) Date: Thu, 22 Mar 2018 09:00:12 +0000 Subject: [ghc-steering-committee] As patterns in pattern synonyms (#94), Recommendation: accept In-Reply-To: <1521409763.6087.13.camel@joachim-breitner.de> References: <1519741198.1113.11.camel@joachim-breitner.de> <1521409763.6087.13.camel@joachim-breitner.de> Message-ID: Thanks. It's implemented in this patch Simon commit 411a97e2c0083529b4259d0cad8f453bae110dee Author: Simon Peyton Jones Date: Wed Mar 21 17:21:15 2018 +0000 Allow as-patterns in unidirectional pattern synonyms | -----Original Message----- | From: ghc-steering-committee On Behalf Of Joachim Breitner | Sent: 18 March 2018 21:49 | To: ghc-steering-committee at haskell.org | Subject: Re: [ghc-steering-committee] As patterns in pattern synonyms | (#94), Recommendation: accept | | Hi, | | I declare consensus; accepted, | | Joachim | | Am Mittwoch, den 28.02.2018, 09:25 +0000 schrieb Simon Marlow: | > Looks good to me. | > | > On 27 February 2018 at 14:19, Joachim Breitner wrote: | > > Dear Committee, | > > | > > this is your secretary speaking: | > > | > > As patterns in pattern synonyms, by Richard. | > > | https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgit | > > hub.com%2Fghc-proposals%2Fghc- | proposals%2Fpull%2F94&data=04%7C01%7Cs | > > | imonpj%40microsoft.com%7C0af532279baa4df1b88308d58d1a25fc%7C72f988bf | > > | 86f141af91ab2d7cd011db47%7C1%7C0%7C636570065804867191%7CUnknown%7CTW | > > | FpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwifQ%3D% | > > 3D%7C- | 1&sdata=ZS2axyI0uDhFDHIeyEkHGg7%2F7XluyVkmoC%2FBs1O8%2F7w%3D&r | > > eserved=0 | > > rendered at | > > | https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgit | > > hub.com%2Fghc-proposals%2Fghc-proposals%2Fblob%2Fas-pattern- | synonyms | > > | %2FAsPatternSynonyms.rst&data=04%7C01%7Csimonpj%40microsoft.com%7C0a | > > | f532279baa4df1b88308d58d1a25fc%7C72f988bf86f141af91ab2d7cd011db47%7C | > > | 1%7C0%7C636570065804867191%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwM | > > DAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwifQ%3D%3D%7C- | 1&sdata=LZMtjxsYvZZ1f | > > h7UQmcv2unRoj8jPmM0rQnmXVlI%2Bno%3D&reserved=0 | > > | > > I’ll shepherd that myself. | > > | > > This proposal removes restrictions on what can be used in | > > unidirectional pattern synonyms, where @-pattern were previously | > > disallowed. The restriction would make sense if patterns synonyms | > > are macros, but they are not. I am always in favor of removing | > > special cases and restrictions, so I recommend to accept this | proposal. | > > | > > Thanks, | > > Joachim | > > -- | > > Joachim Breitner | > > mail at joachim-breitner.de | > > | > > | https://na01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fwww. | > > joachim- | breitner.de%2F&data=04%7C01%7Csimonpj%40microsoft.com%7C0af5 | > > | 32279baa4df1b88308d58d1a25fc%7C72f988bf86f141af91ab2d7cd011db47%7C1% | > > | 7C0%7C636570065804877199%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDA | > > iLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwifQ%3D%3D%7C- | 1&sdata=kssVfS3sxZhFYaO | > > dS6xDlnLs6tbKs66bkqosHPSOQk0%3D&reserved=0 | > > | > > _______________________________________________ | > > ghc-steering-committee mailing list | > > ghc-steering-committee at haskell.org | > > https://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-steering- | commi | > > ttee | > > | > | > _______________________________________________ | > ghc-steering-committee mailing list | > ghc-steering-committee at haskell.org | > https://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-steering- | committ | > ee | -- | Joachim Breitner | mail at joachim-breitner.de | | https://na01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fwww.jo | achim- | breitner.de%2F&data=04%7C01%7Csimonpj%40microsoft.com%7C0af532279baa4d | f1b88308d58d1a25fc%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C636570 | 065804877199%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luM | zIiLCJBTiI6Ik1haWwifQ%3D%3D%7C- | 1&sdata=kssVfS3sxZhFYaOdS6xDlnLs6tbKs66bkqosHPSOQk0%3D&reserved=0 From simonpj at microsoft.com Thu Mar 22 12:26:20 2018 From: simonpj at microsoft.com (Simon Peyton Jones) Date: Thu, 22 Mar 2018 12:26:20 +0000 Subject: [ghc-steering-committee] =?utf-8?q?Proposal_=2379_=22Add_a_=3Akin?= =?utf-8?q?d!!_command_to_ghci=22_=E2=80=94_propose_yes?= In-Reply-To: <1A21C65F-1761-47F1-B922-E70BFFE12CAB@justtesting.org> References: <1A21C65F-1761-47F1-B922-E70BFFE12CAB@justtesting.org> Message-ID: Like Richard * I like the goal * I hate the proposed command :kind! I suppose we could add :eval as a way to evaluate ; a long-form of and then :eval type for this proposal. Simon | -----Original Message----- | From: ghc-steering-committee On Behalf Of Manuel M T Chakravarty | Sent: 21 March 2018 02:43 | To: ghc-steering-committee at haskell.org | Subject: [ghc-steering-committee] Proposal #79 "Add a :kind!! command | to ghci" — propose yes | | We need to decide on the Proposal #79 ”Add a :kind!! command to ghci, | to expand type families and type synonyms”: | | (rendered) | https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithu | b.com%2Falpmestan%2Fghc-proposals%2Fblob%2Fmaster%2Fproposals%2F0000- | kind-bang- | bang.rst&data=04%7C01%7Csimonpj%40microsoft.com%7Cc5767d25630244346d5a | 08d58ed5770e%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C636571969830 | 865127%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJ | BTiI6Ik1haWwifQ%3D%3D%7C- | 1&sdata=TiBF9Hg1BxieAB2B6Naez9FWiX53Hhfg0BP%2B%2F3MKjHs%3D&reserved=0 | (discussion) | https://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithu | b.com%2Fghc-proposals%2Fghc- | proposals%2Fpull%2F79&data=04%7C01%7Csimonpj%40microsoft.com%7Cc5767d2 | 5630244346d5a08d58ed5770e%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7 | C636571969830865127%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIj | oiV2luMzIiLCJBTiI6Ik1haWwifQ%3D%3D%7C- | 1&sdata=VhEDSDfQQM19L3sY1yyuT5cHJ24jroBSdVg19DVWZiE%3D&reserved=0 | | I agree that this is useful functionality and it is a simple change to | GHCi. There has been some discussion about the naming of this command, | but TBH I didn’t find any of the alternatives more convincing than | ”:kind!!”, so I’d suggest to stick with that. | | I favour accepting this proposal. Are there any dissenting opinions? | | Cheers, | Manuel | | _______________________________________________ | ghc-steering-committee mailing list | ghc-steering-committee at haskell.org | https://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-steering- | committee From simonpj at microsoft.com Thu Mar 22 15:15:39 2018 From: simonpj at microsoft.com (Simon Peyton Jones) Date: Thu, 22 Mar 2018 15:15:39 +0000 Subject: [ghc-steering-committee] Treat kind and type vars identically with `forall` #103 Message-ID: Dear GHC steering committee I strongly propose that we accept Treat kind and type vars identically with `forall` #103 https://github.com/ghc-proposals/ghc-proposals/pull/103 It makes our design much more simple and uniform - both in the specification and in the implementation. The current setup is a terrible dogs breakfast. Moreover, I propose that we adopt it without a 3-release wait after #83 - see under Alternatives. Any programs that are rejected by #103 can be fixed by adding some extra forall k's. And that change will be accepted NOW if you add -XTypeInType. Simon -------------- next part -------------- An HTML attachment was scrubbed... URL: From rae at cs.brynmawr.edu Thu Mar 22 15:52:39 2018 From: rae at cs.brynmawr.edu (Richard Eisenberg) Date: Thu, 22 Mar 2018 11:52:39 -0400 Subject: [ghc-steering-committee] Treat kind and type vars identically with `forall` #103 In-Reply-To: References: Message-ID: > On Mar 22, 2018, at 11:15 AM, Simon Peyton Jones wrote: > > Dear GHC steering committee > > I strongly propose that we accept > > Treat kind and type vars identically with `forall` #103 > Agreed, unsurprisingly. > Moreover, I propose that we adopt it without a 3-release wait after #83 – see under Alternatives. Any programs that are rejected by #103 can be fixed by adding some extra forall k’s. And that change will be accepted NOW if you add -XTypeInType. > Here I disagree. Enabling -XTypeInType has two unfortunate knock-on effects: - * is no longer available in kinds, without import Data.Kind. Happily, GHC gives a good error message upon a forgotten `import Data.Kind`, so this isn't so bad, but it will bite very widely. - More troublesomely, the CUSK rules are different with -XTypeInType than without. This means that turning on -XTypeInType can turn some CUSKs into non-CUSKs, producing utterly befuddling error messages. Maybe this won't bite so often, but when it does, it will take a developer a long time to sort out the problem. After #83, these problems melt away, but I think it will be painful for users to support multiple versions in the meantime. Richard > 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 ben at well-typed.com Thu Mar 22 23:59:14 2018 From: ben at well-typed.com (Ben Gamari) Date: Thu, 22 Mar 2018 19:59:14 -0400 Subject: [ghc-steering-committee] Plugin recompilation avoidance interface (#108) In-Reply-To: <87ina2z74g.fsf@smart-cactus.org> References: <87a7w4uzt8.fsf@smart-cactus.org> <87tvtypfw2.fsf@smart-cactus.org> <1520259286.1311.10.camel@joachim-breitner.de> <87ina2z74g.fsf@smart-cactus.org> Message-ID: <87tvt7k6gj.fsf@smart-cactus.org> Ben Gamari writes: > Joachim Breitner writes: > >> And even if, in the future, we have ability to provide a finer grained >> mechanism, we can add the necessary functions _then_ when we know how >> it looks. >> > Your argument is pretty compelling. I'll admit that part of my dislike > of the the simple approach that you advocate is purely aesthetic; it > just feels terribly ad-hoc. That being said, you do raise a valid point > that we really don't know enough to be able to say what a more precise > interface would look like. > > Moreover, there is something to be said for the nice > backwards-compatibility story that the simple approach allows. > > I would be fine accepting the simple approach. Either way, I think we > should move this proposal forward to unblock our contributor. > Does anyone object to accepting the simple approach as suggested by Joachim? Cheers, - Ben -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 487 bytes Desc: not available URL: From rleshchinskiy at gmail.com Sun Mar 25 22:23:43 2018 From: rleshchinskiy at gmail.com (Roman Leshchinskiy) Date: Sun, 25 Mar 2018 23:23:43 +0100 Subject: [ghc-steering-committee] Proposal: Binding existential type variables (#96) Message-ID: Hi everyone, The proposal is to add a way to name existential type variables in pattern matches: https://github.com/ghc-proposals/ghc-proposals/pull/96. Suppose we have a constructor with an existential: data T where MkT :: forall a. Show a => a -> T Under the proposal, we could then bind that existential in a match against MkT: f :: T -> String f (MkT @a x) = show (x :: a) Note that this reuses the syntax for visible type application. Only the forms @a (where 'a' is a variable) and @_ are permitted. In the discussion the following major questions have been raised. 1. What about universally quantified type variables, such as 'a' in the following definition: data U a where MkU :: forall a b. Show a => b -> T a Do we need to mention 'a' in a pattern match against MkU? The answer (now reflected in the proposal) is no - universally quantified type variables can't be bound in this way. The pattern would look like this: g :: U a -> String g (MkU @b x) = show (x :: b) The bulk of the discussion was about this question. 2. What exactly is an existential? The above examples are clear but what about: type family Id a where Id a = a data T a where MkT :: forall a. a -> T (Id a) This is an existential under the current rules but given this, the distinction between existentials and universals might be not entirely intuitive. 3. What about pattern synonyms? The proposal now clarifies that they are treated exactly the same as data constructors. My recommendation is to reject the proposal as is but to encourage the authors to come up with a different syntax. The reason is that the proposal "steals" the syntax for explicit type application in patterns but it seems to me that type application in patterns makes perfect sense! I don't see why I shouldn't be eventually able to write something like: data C a = C a h (C @Int n) = n and have the compiler infer h :: C Int -> Int. Having @type mean something other than type application in pattern seems highly confusing to me and kills a possibly useful future feature. I believe a lot of the confusion with respect to point 1 above happened precisely because the proposal blurs the difference between type application and binding in patterns. As to syntax, perhaps using 'type' or 'forall' as type binders instead of '@' would work. Thanks, Roman -------------- next part -------------- An HTML attachment was scrubbed... URL: From simonpj at microsoft.com Mon Mar 26 07:59:29 2018 From: simonpj at microsoft.com (Simon Peyton Jones) Date: Mon, 26 Mar 2018 07:59:29 +0000 Subject: [ghc-steering-committee] Proposal: Binding existential type variables (#96) In-Reply-To: References: Message-ID: The reason is that the proposal "steals" the syntax for explicit type application in patterns but it seems to me that type application in patterns makes perfect sense! I disagree with Roman here. I don’t think type application makes sense in patterns. Suppose we have data T a where MkT :: [a] -> [b] -> T a f :: T c -> c -> [c] f t x = x : (case t of T ys zs -> if length zs > 1 then ys else []) Then * ‘c’ is really bound at f’s definition site; not in the pattern match * You might want to mention ‘c’ in lots of places, not just inside the pattern match, so you might want to make ‘c’ lexically scope over its entire actual scope. Providing a convenient way to make it scope over just part of its actual scope seems entirely ad-hoc. We might want to do that at any sub-expression. And we can do so with an ordinary type signature with an explicit forall. * In contrast the type of ‘zs’ really is bound at the pattern match. * Imagine that we had a type-passing implementation that really did pass data structures representing types for every big lambda and type application. Then we really would store the data structure representing the existential inside the data constructor, and match it in a pattern; but it would be a waste of space to store and match the universal too. * In Core, we have MkT :: forall a b . [a] -> [b] -> T a, so a use of MkT as a constructor is applied to two types. But in a pattern match we just match one type, namely the existential one. I think the proposal is a fine one! Let’s accept it. Simon From: ghc-steering-committee On Behalf Of Roman Leshchinskiy Sent: 25 March 2018 23:24 To: ghc-steering-committee at haskell.org Subject: [ghc-steering-committee] Proposal: Binding existential type variables (#96) Hi everyone, The proposal is to add a way to name existential type variables in pattern matches: https://github.com/ghc-proposals/ghc-proposals/pull/96. Suppose we have a constructor with an existential: data T where MkT :: forall a. Show a => a -> T Under the proposal, we could then bind that existential in a match against MkT: f :: T -> String f (MkT @a x) = show (x :: a) Note that this reuses the syntax for visible type application. Only the forms @a (where 'a' is a variable) and @_ are permitted. In the discussion the following major questions have been raised. 1. What about universally quantified type variables, such as 'a' in the following definition: data U a where MkU :: forall a b. Show a => b -> T a Do we need to mention 'a' in a pattern match against MkU? The answer (now reflected in the proposal) is no - universally quantified type variables can't be bound in this way. The pattern would look like this: g :: U a -> String g (MkU @b x) = show (x :: b) The bulk of the discussion was about this question. 2. What exactly is an existential? The above examples are clear but what about: type family Id a where Id a = a data T a where MkT :: forall a. a -> T (Id a) This is an existential under the current rules but given this, the distinction between existentials and universals might be not entirely intuitive. 3. What about pattern synonyms? The proposal now clarifies that they are treated exactly the same as data constructors. My recommendation is to reject the proposal as is but to encourage the authors to come up with a different syntax. The reason is that the proposal "steals" the syntax for explicit type application in patterns but it seems to me that type application in patterns makes perfect sense! I don't see why I shouldn't be eventually able to write something like: data C a = C a h (C @Int n) = n and have the compiler infer h :: C Int -> Int. Having @type mean something other than type application in pattern seems highly confusing to me and kills a possibly useful future feature. I believe a lot of the confusion with respect to point 1 above happened precisely because the proposal blurs the difference between type application and binding in patterns. As to syntax, perhaps using 'type' or 'forall' as type binders instead of '@' would work. Thanks, Roman -------------- next part -------------- An HTML attachment was scrubbed... URL: From simonpj at microsoft.com Mon Mar 26 09:24:02 2018 From: simonpj at microsoft.com (Simon Peyton Jones) Date: Mon, 26 Mar 2018 09:24:02 +0000 Subject: [ghc-steering-committee] Proposal: Binding existential type variables (#96) In-Reply-To: References: Message-ID: Note we aren't binding any type variables here, we're just selecting a specific instantiation of the constructor via type application Interesting. (I did misunderstand you!) So in your example, Int and only Int would do at that spot. To you it seems like a “natural meaning” but not to me. In a pattern I expect to enumerate the bound variables, and that is just what is proposed here, * using @ to distinguish type binders from term binders just as visible type application * uses @ to distinguish type argument from term arguments Also, you can readily do what you want with an ordinary type signature in a pattern h (C n :: C Int) = n -- infers h :: C Int -> Int Moreover you don’t explain what it would mean to supply the existential argument with @ applications in a pattern match. Do those bind type variables? I think we should be cautious about rejecting one proposal because it precludes another, unless the other is actually made and worked out so we can see it. I say cautious, not that it’s an invalid argument – we don’t want to accept proposals that everyone agrees will preclude future flexibility. But here it is controversial (at least between you and me 😊). Would you like to make an alternative proposal? Simon From: Roman Leshchinskiy Sent: 26 March 2018 09:54 To: Simon Peyton Jones Subject: Re: [ghc-steering-committee] Proposal: Binding existential type variables (#96) On Mon, Mar 26, 2018 at 8:59 AM, Simon Peyton Jones > wrote: The reason is that the proposal "steals" the syntax for explicit type application in patterns but it seems to me that type application in patterns makes perfect sense! I disagree with Roman here. I don’t think type application makes sense in patterns. Suppose we have data T a where MkT :: [a] -> [b] -> T a f :: T c -> c -> [c] f t x = x : (case t of T ys zs -> if length zs > 1 then ys else []) Then · ‘c’ is really bound at f’s definition site; not in the pattern match · You might want to mention ‘c’ in lots of places, not just inside the pattern match, so you might want to make ‘c’ lexically scope over its entire actual scope. Providing a convenient way to make it scope over just part of its actual scope seems entirely ad-hoc. We might want to do that at any sub-expression. And we can do so with an ordinary type signature with an explicit forall. · In contrast the type of ‘zs’ really is bound at the pattern match. · Imagine that we had a type-passing implementation that really did pass data structures representing types for every big lambda and type application. Then we really would store the data structure representing the existential inside the data constructor, and match it in a pattern; but it would be a waste of space to store and match the universal too. · In Core, we have MkT :: forall a b . [a] -> [b] -> T a, so a use of MkT as a constructor is applied to two types. But in a pattern match we just match one type, namely the existential one. Simon, I think you might have misunderstood me. I'm not proposing to be able to *bind* universally quantified variables via @ in patterns. My argument is much simpler. To revisit my example: data C a = C a This gives us the constructor C :: forall a. a -> a and in expressions, C @Int is the Int -> Int instance of the constructor. Personally, I would expect C @Int to have the exact same meaning in patterns since it makes total sense there (to me, at least), like in my example: h (C @Int n) = n -- infers h :: C Int -> Int Note we aren't binding any type variables here, we're just selecting a specific instantiation of the constructor via type application, just like we would do in expressions. Under the proposal, the meaning of @ in patterns would be different and to me, surprising. In fact, I naively assumed that the above is already possible with visible type application. Now, perhaps type application in patterns isn't and will never be useful and repurposing the syntax is ok? After all, patterns already reuse function application syntax in much the same way. I'll certainly reconsider my opinion if that's the case but I don't think this has been discussed at all so far. Hence, I'm very wary of taking away syntax that already has a natural meaning. Roman -------------- next part -------------- An HTML attachment was scrubbed... URL: From mail at joachim-breitner.de Mon Mar 26 14:31:58 2018 From: mail at joachim-breitner.de (Joachim Breitner) Date: Mon, 26 Mar 2018 10:31:58 -0400 Subject: [ghc-steering-committee] Proposal: Binding existential type variables (#96) In-Reply-To: References: Message-ID: <1522074718.24566.7.camel@joachim-breitner.de> Hi, without adding much to the discussion, I agree with Roman’s sentiment here. And maybe that is an indication that more people out there, who are not as deep into the theory and implementation of this feature, will be similarly surprised. Am Montag, den 26.03.2018, 09:24 +0000 schrieb Simon Peyton Jones: > Also, you can readily do what you want with an ordinary type > signature in a pattern > > h (C n :: C Int) = n -- infers h :: C Int -> Int Isn’t that true for most uses of TypeApplications in expressions as well, that they could readily be replaced by type signatures? And yet we offer the TypeApplications extension? Here is another example where the current proposal superficially breaks the nice equational nature of Haskell: data U a where MkU :: forall a b. Show a => b -> T a idU :: forall a. U a -> U a idU (MkU @b x) = MkU @a @b x or even idU :: forall a. U a -> U a idU (MkU @b x) = MkU @a x It is the identity! Why don’t I write the same things on both sides? I think all reserverations would disappear if we can find a good syntax for existential type variable that does not clash with TypeApplication. Maybe @? instead of @ (given that ? is commonly used to refer to ∃)? Cheers, Joachim -- Joachim Breitner mail at joachim-breitner.de http://www.joachim-breitner.de/ -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 833 bytes Desc: This is a digitally signed message part URL: From simonpj at microsoft.com Mon Mar 26 16:02:24 2018 From: simonpj at microsoft.com (Simon Peyton Jones) Date: Mon, 26 Mar 2018 16:02:24 +0000 Subject: [ghc-steering-committee] Proposal: Binding existential type variables (#96) In-Reply-To: <1522074718.24566.7.camel@joachim-breitner.de> References: <1522074718.24566.7.camel@joachim-breitner.de> Message-ID: | I think all reserverations would disappear if we can find a good | syntax for existential type variable that does not clash with | TypeApplication. I really don't agree. If we wrote f (?x : ?xs) = ... to signal that x and xs were binding sites, then I'd be fine with writing f (MkT @?a ?xs) = ... But we don’t. In patterns, a plain variable is a binding site. And it should be the same for types -- save that we need a way to distinguish terms from types, just as we do in terms. You should think of * the universal type args and required dictionaries, as INPUTs to the match * the existential args and value args, as OUTPUTS of the match Consider data T p where MkT :: p -> [q] -> T p f :: forall a. (Num a, Eq a) => T a -> Int f (T 3 y) = length y Here, the type 'a' and the dictionaries for (Eq a, Num a) are inputs to the match. If successful, the match binds the existential type 'q', and value argument (y :: [q]). A matcher for the pattern (T 3 y) would have a type like forall a r. (Num a, Eq a) => (forall q. [q] -> r) -> T a -> r Now, the things matched by the pattern are the arguments (both type and term arguments) to that continuation. These are what I expect to see bound. As a programmer you really do need to know which variables are existential. Without that you can't possibly know what programs are well typed. It seems so simple to me to say "we use the @ to distinguish between term and type arguments in applications; and between term and type binders in patterns". Simon | -----Original Message----- | From: ghc-steering-committee On Behalf Of Joachim Breitner | Sent: 26 March 2018 15:32 | To: ghc-steering-committee at haskell.org | Subject: Re: [ghc-steering-committee] Proposal: Binding existential | type variables (#96) | | Hi, | | without adding much to the discussion, I agree with Roman’s sentiment | here. And maybe that is an indication that more people out there, who | are not as deep into the theory and implementation of this feature, | will be similarly surprised. | | Am Montag, den 26.03.2018, 09:24 +0000 schrieb Simon Peyton Jones: | > Also, you can readily do what you want with an ordinary type | signature | > in a pattern | > | > h (C n :: C Int) = n -- infers h :: C Int -> Int | | Isn’t that true for most uses of TypeApplications in expressions as | well, that they could readily be replaced by type signatures? And yet | we offer the TypeApplications extension? | | Here is another example where the current proposal superficially | breaks the nice equational nature of Haskell: | | data U a where MkU :: forall a b. Show a => b -> T a | | idU :: forall a. U a -> U a | idU (MkU @b x) = MkU @a @b x | | or even | | idU :: forall a. U a -> U a | idU (MkU @b x) = MkU @a x | | It is the identity! Why don’t I write the same things on both sides? | | | I think all reserverations would disappear if we can find a good | syntax for existential type variable that does not clash with | TypeApplication. | | Maybe @? instead of @ (given that ? is commonly used to refer to ∃)? | | Cheers, | Joachim | -- | Joachim Breitner | mail at joachim-breitner.de | | https://na01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fwww.jo | achim- | breitner.de%2F&data=02%7C01%7Csimonpj%40microsoft.com%7Cecf2cfd38b0947 | 25e09d08d593265bd5%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C636576 | 715317265122&sdata=H5kvHXEYy9L7Pnp3CyajY9BFbhkuzHhqrxxR5xykx0M%3D&rese | rved=0 From rae at cs.brynmawr.edu Mon Mar 26 16:44:28 2018 From: rae at cs.brynmawr.edu (Richard Eisenberg) Date: Mon, 26 Mar 2018 12:44:28 -0400 Subject: [ghc-steering-committee] Proposal: Binding existential type variables (#96) In-Reply-To: <1522074718.24566.7.camel@joachim-breitner.de> References: <1522074718.24566.7.camel@joachim-breitner.de> Message-ID: I'm of several minds on this issue. 1. Like Joachim, I really like expressions and patterns to have a similar structure. The lack of this feature in this proposal irks me. 2. Like Roman, I see the value in being able to specialize universal variables in patterns. This is not an overwhelming desire, but I see the point here. 3. Like Simon, I see the value in being able to say that everything that occurs in a pattern is a pattern -- that is, an output of the match. On balance, I think (3) outweighs (2). A programmer should be able to tell, just based on concrete syntax alone, whether a variable mention in a program is a *binding site* or *occurrence*. Currently, variables that appear after a constructor in a pattern are binding sites. That suggests that type variables appearing after @ in patterns should also be binding sites. (This agrees with the proposal.) As for (1), perhaps we simply accept that patterns and expressions really are different. It's quite like how a pattern synonym type has to have two separate sets of constraints (one is required and one is provided) when being used as a pattern, but these constraints get smooshed together when the pattern synonym is used in an expression. And I agree with Simon that the programmer needs to know what the existentials are to have any hope of writing type-correct code. I am thus in favor of the proposal, but acknowledging these soft spots. Richard > On Mar 26, 2018, at 10:31 AM, Joachim Breitner wrote: > > Hi, > > without adding much to the discussion, I agree with Roman’s sentiment > here. And maybe that is an indication that more people out there, who > are not as deep into the theory and implementation of this feature, > will be similarly surprised. > > Am Montag, den 26.03.2018, 09:24 +0000 schrieb Simon Peyton Jones: >> Also, you can readily do what you want with an ordinary type >> signature in a pattern >> >> h (C n :: C Int) = n -- infers h :: C Int -> Int > > Isn’t that true for most uses of TypeApplications in expressions as > well, that they could readily be replaced by type signatures? And yet > we offer the TypeApplications extension? > > Here is another example where the current proposal superficially breaks > the nice equational nature of Haskell: > > data U a where MkU :: forall a b. Show a => b -> T a > > idU :: forall a. U a -> U a > idU (MkU @b x) = MkU @a @b x > > or even > > idU :: forall a. U a -> U a > idU (MkU @b x) = MkU @a x > > It is the identity! Why don’t I write the same things on both sides? > > > I think all reserverations would disappear if we can find a good syntax > for existential type variable that does not clash with > TypeApplication. > > Maybe @? instead of @ (given that ? is commonly used to refer to ∃)? > > 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 mail at joachim-breitner.de Mon Mar 26 18:22:41 2018 From: mail at joachim-breitner.de (Joachim Breitner) Date: Mon, 26 Mar 2018 14:22:41 -0400 Subject: [ghc-steering-committee] Proposal: Binding existential type variables (#96) In-Reply-To: References: <1522074718.24566.7.camel@joachim-breitner.de> Message-ID: <1522088561.24566.36.camel@joachim-breitner.de> Hi, I know that it is frowned upon to discuss the merits of one proposal with hypothetical future proposals in mind, but I can’t resist: Am Montag, den 26.03.2018, 12:44 -0400 schrieb Richard Eisenberg: > 3. Like Simon, I see the value in being able to say that everything > that occurs in a pattern is a pattern -- that is, an output of the > match. I wonder if raising this current state to a principle blocks us from very useful future extensions. In particular, I expect that in the future we will want to be able to abstract pattern synonyms over values, and be able to do something like the following, given in infeasible syntax. pattern Nths n x <- ((!! ns) -> x) squareTenth :: [Int] -> Int squareTenth (Nths 10 x) = x*x or nths :: Int -> [a] -> a nths n (Nths n x) = x Ah, and of course view patterns already break the rule that “everything that occurs in a pattern is a pattern”! So somewhere down the line, I expect that patterns with have both INPUT and OUTPUT terms, and I will be able to specify both. In the same vain, I would like to be able to specify both INPUT and OUTPUT types now. And just in case this is a course of confusion: Nobody proposes to _bind_ universal variables. But Romand and me are missing a way of explicitly _instantiating_ universal variables. The proposal only discuss the former (which I agree is bogus), but not the latter. Cheers, Joachim -- Joachim Breitner mail at joachim-breitner.de http://www.joachim-breitner.de/ -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 833 bytes Desc: This is a digitally signed message part URL: From rae at cs.brynmawr.edu Mon Mar 26 18:34:13 2018 From: rae at cs.brynmawr.edu (Richard Eisenberg) Date: Mon, 26 Mar 2018 14:34:13 -0400 Subject: [ghc-steering-committee] Proposal: Binding existential type variables (#96) In-Reply-To: <1522088561.24566.36.camel@joachim-breitner.de> References: <1522074718.24566.7.camel@joachim-breitner.de> <1522088561.24566.36.camel@joachim-breitner.de> Message-ID: <90ADE520-4E5F-4BCA-B11E-2DB89898F01E@cs.brynmawr.edu> I've had a similar idea. However, Simon once convinced me that we would want some syntactic distinction between inputs and outputs: otherwise a reader of code wouldn't differentiate variable occurrences from variable bindings. For example: f x y = case y of P x x -> ... Note that I haven't given the type of P. In the pattern there, is the first x an occurrence while the second a new binding that shadows the outer x? Or is the first x a binding and the second one an occurrence? Or are they both occurrences? (They can't both be bindings!) A type system could, in theory, sort this out, but then the renamer behavior would have to depend on types. And it's terribly confusing for readers. So if we want to consider this future extension, we should have a syntactic marker for the inputs. Perhaps using * would remind C programmers of dereferencing: f x y = case y of P *x x -> ... Now it's all very clear! (Well, maybe not *very* clear.) But we can unambiguously say that the first x is an occurrence of the outer x and the second is a binding site of a shadowing variable. Bringing this back to the proposal at hand, we would say this to mention a universal: g (Just *@Int x) = x and that would mean g :: Maybe Int -> Int Of course, these little syntactic sigils make Haskell look more Perlish, and that's not a good thing. Richard > On Mar 26, 2018, at 2:22 PM, Joachim Breitner wrote: > > Hi, > > I know that it is frowned upon to discuss the merits of one proposal > with hypothetical future proposals in mind, but I can’t resist: > > Am Montag, den 26.03.2018, 12:44 -0400 schrieb Richard Eisenberg: >> 3. Like Simon, I see the value in being able to say that everything >> that occurs in a pattern is a pattern -- that is, an output of the >> match. > > I wonder if raising this current state to a principle blocks us from > very useful future extensions. In particular, I expect that in the > future we will want to be able to abstract pattern synonyms over > values, and be able to do something like the following, given in > infeasible syntax. > > pattern Nths n x <- ((!! ns) -> x) > > squareTenth :: [Int] -> Int > squareTenth (Nths 10 x) = x*x > > or > > nths :: Int -> [a] -> a > nths n (Nths n x) = x > > > Ah, and of course view patterns already break the rule that “everything > that occurs in a pattern is a pattern”! > > > So somewhere down the line, I expect that patterns with have both INPUT > and OUTPUT terms, and I will be able to specify both. In the same vain, > I would like to be able to specify both INPUT and OUTPUT types now. > > > And just in case this is a course of confusion: Nobody proposes to > _bind_ universal variables. But Romand and me are missing a way of > explicitly _instantiating_ universal variables. The proposal only > discuss the former (which I agree is bogus), but not the latter. > > > > 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 mail at joachim-breitner.de Mon Mar 26 18:43:59 2018 From: mail at joachim-breitner.de (Joachim Breitner) Date: Mon, 26 Mar 2018 14:43:59 -0400 Subject: [ghc-steering-committee] Proposal: Binding existential type variables (#96) In-Reply-To: <90ADE520-4E5F-4BCA-B11E-2DB89898F01E@cs.brynmawr.edu> References: <1522074718.24566.7.camel@joachim-breitner.de> <1522088561.24566.36.camel@joachim-breitner.de> <90ADE520-4E5F-4BCA-B11E-2DB89898F01E@cs.brynmawr.edu> Message-ID: <1522089839.24566.44.camel@joachim-breitner.de> Hi, Am Montag, den 26.03.2018, 14:34 -0400 schrieb Richard Eisenberg: > Bringing this back to the proposal at hand, we would say this to > mention a universal: > > g (Just *@Int x) = x > > and that would mean g :: Maybe Int -> Int Yes! Something like that and I would fully support the proposal. But > Of course, these little syntactic sigils make Haskell look more > Perlish, and that's not a good thing. is spot-on, and finding a good syntax is the hard part here. And once we have syntax to instantiate universals and bind existentials, there is the question, which of these two deserves @ and which has to get the yet-to-be-found other one. (Personally, I’d say that @ should instantiate universals, for consistency with TypeApplications, but will not insist on this point.) Somewhat tangentially, how much should it worry us that according to the current proposal, in type Id a = a data Foo a where MkFoo :: forall a, a -> Foo a data Foo' a where MkFoo' :: forall a, a -> Foo (Id a) the constructors MkFoo and MkFoo' behave totally different wrt universals and existentials? I see the technical justification for it, but it still feels odd and unsmooth. Cheers, Joachim -- Joachim Breitner mail at joachim-breitner.de http://www.joachim-breitner.de/ -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 833 bytes Desc: This is a digitally signed message part URL: From rae at cs.brynmawr.edu Mon Mar 26 20:28:57 2018 From: rae at cs.brynmawr.edu (Richard Eisenberg) Date: Mon, 26 Mar 2018 16:28:57 -0400 Subject: [ghc-steering-committee] Proposal: Binding existential type variables (#96) In-Reply-To: <1522089839.24566.44.camel@joachim-breitner.de> References: <1522074718.24566.7.camel@joachim-breitner.de> <1522088561.24566.36.camel@joachim-breitner.de> <90ADE520-4E5F-4BCA-B11E-2DB89898F01E@cs.brynmawr.edu> <1522089839.24566.44.camel@joachim-breitner.de> Message-ID: <348DA9F2-FAE1-46A5-B57C-FE36EF4B55FA@cs.brynmawr.edu> > On Mar 26, 2018, at 2:43 PM, Joachim Breitner wrote: > And once we have syntax to instantiate universals and bind > existentials, there is the question, which of these two deserves @ and > which has to get the yet-to-be-found other one. (Personally, I’d say > that @ should instantiate universals, for consistency with > TypeApplications, but will not insist on this point.) And I'd say that @ should bind existentials, for consistency with the usual default for patterns, which is the "output" mode. Besides, I think binding existentials will be much more common than instantiating universals. > > > > Somewhat tangentially, how much should it worry us that according to > the current proposal, in > > type Id a = a > data Foo a where MkFoo :: forall a, a -> Foo a > data Foo' a where MkFoo' :: forall a, a -> Foo (Id a) > > the constructors MkFoo and MkFoo' behave totally different wrt > universals and existentials? I see the technical justification for it, > but it still feels odd and unsmooth. The rule in the proposal is dumb-and-predictable, far better than clever-and-abstruse. GHC is clever-and-abstruse enough as it is -- we should claim dumb-and-predictable where we can find it. :) Richard > > > 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 rleshchinskiy at gmail.com Mon Mar 26 21:54:21 2018 From: rleshchinskiy at gmail.com (Roman Leshchinskiy) Date: Mon, 26 Mar 2018 22:54:21 +0100 Subject: [ghc-steering-committee] Proposal: Binding existential type variables (#96) In-Reply-To: <348DA9F2-FAE1-46A5-B57C-FE36EF4B55FA@cs.brynmawr.edu> References: <1522074718.24566.7.camel@joachim-breitner.de> <1522088561.24566.36.camel@joachim-breitner.de> <90ADE520-4E5F-4BCA-B11E-2DB89898F01E@cs.brynmawr.edu> <1522089839.24566.44.camel@joachim-breitner.de> <348DA9F2-FAE1-46A5-B57C-FE36EF4B55FA@cs.brynmawr.edu> Message-ID: On Mon, Mar 26, 2018 at 9:28 PM, Richard Eisenberg wrote: > > > > On Mar 26, 2018, at 2:43 PM, Joachim Breitner > wrote: > > > And once we have syntax to instantiate universals and bind > > existentials, there is the question, which of these two deserves @ and > > which has to get the yet-to-be-found other one. (Personally, I’d say > > that @ should instantiate universals, for consistency with > > TypeApplications, but will not insist on this point.) > > And I'd say that @ should bind existentials, for consistency with the > usual default for patterns, which is the "output" mode. Besides, I think > binding existentials will be much more common than instantiating universals. > The point about inputs vs. outputs to patterns has clarified things a lot for me, thanks! I think that if we ever want to allow inputs to patterns, we could just use a reserved token to separate those (assuming all inputs come before the outputs). Something like this (\ already means "here come binders"): C \ Then @ would instantiate universals before \ and bind existentials after and \ could be omitted if there are no inputs, thus subsuming the current pattern syntax. In any event, this convinces me that we won't be irrevocably taking away syntax which might prove essential in the future and I now support the proposal. Roman -------------- next part -------------- An HTML attachment was scrubbed... URL: From rae at cs.brynmawr.edu Tue Mar 27 02:47:27 2018 From: rae at cs.brynmawr.edu (Richard Eisenberg) Date: Mon, 26 Mar 2018 22:47:27 -0400 Subject: [ghc-steering-committee] Proposal: Binding existential type variables (#96) In-Reply-To: References: <1522074718.24566.7.camel@joachim-breitner.de> <1522088561.24566.36.camel@joachim-breitner.de> <90ADE520-4E5F-4BCA-B11E-2DB89898F01E@cs.brynmawr.edu> <1522089839.24566.44.camel@joachim-breitner.de> <348DA9F2-FAE1-46A5-B57C-FE36EF4B55FA@cs.brynmawr.edu> Message-ID: <83DE2F77-F70E-4B7E-8875-CE6BC60CE211@cs.brynmawr.edu> > On Mar 26, 2018, at 5:54 PM, Roman Leshchinskiy wrote: > > C \ I had been trying to figure out how to get \ involved, and this is the way. Thanks! It does require that all inputs come before all outputs, which might not be true for constructors: data T a where MkT :: forall b a. b -> T a Here, `b` is an output while `a` would be an input. And in many cases constructors designed with visible type application in mind will want to put existentials ("outputs") before universals ("inputs"). If we ever did the C \ in the future, I suppose we could just say that such constructors will have their type variables reordered, perhaps issuing a warning if someone writes a mis-ordered constructor. In any case, I'm glad that this discussion has changed your mind about accepting this proposal. Thanks, Richard -------------- next part -------------- An HTML attachment was scrubbed... URL: From rae at cs.brynmawr.edu Tue Mar 27 03:35:42 2018 From: rae at cs.brynmawr.edu (Richard Eisenberg) Date: Mon, 26 Mar 2018 23:35:42 -0400 Subject: [ghc-steering-committee] DH quantifiers (#102), Recommendation: accept In-Reply-To: References: <1519400339.28221.25.camel@joachim-breitner.de> Message-ID: <32A4865D-5D1A-4B90-9FD3-7BB1356E0626@cs.brynmawr.edu> I'd like to restart this thread, both as the Grand Poobah of Dependent Haskell and because Proposal #102 (this one) is holding up #81 (the `forall x y z ->` syntax), which is, in turn, holding up #54 (a plan to eliminate the need for CUSKs), which is implicated in quite a few bugs. I think Iavor makes some good criticisms below, which I'll address individually: > On Feb 23, 2018, at 12:12 PM, Iavor Diatchki wrote: > > * it is premature to "reserve" syntax for a future extension This is a hard one. The full implementation of dependent types in Haskell is still years away. But decisions we make now may affect the eventual concrete syntax. While a ghc-proposal is ill-fitted with reserving syntax, I think Roman was right to request that #81 be considered in the context of the larger syntactic changes. Maybe the "right" answer here is for the committee to conclude that the proposed syntax is generally plausible, paving the way for #81 but without making a solid commitment. On the other hand, if we can identify a better syntax for the overall design of dependent types in Haskell, that might affect the syntax used in #81/#54. > * I am not convinced that a design with 12 quantifiers is what I'd want to use Neither am I! For a moment, let's take the desire for dependent types to be a given. (I'll address this more below.) GHC currently has 3 quantifiers (`forall a.`, `ty ->`, and `ty =>`). To preserve type erasure, we need to distinguish between arguments needed at runtime and those that can be erased. Coq does this through its Set-vs-Prop mechanism, where erased arguments live in their own sort. Such a route is viable for Haskell, I think, but I've never been much enamored of it, personally. For example, the Nat in a vector type really can be erased, while Nats in many other places can't be, and it seems a shame to need two different Nat types to pull off this dichotomy. Agda uses the term "irrelevant" to describe type indices that are ignored during type equality checks. This is related to the type erasure property, but it's not quite the same thing. It's unclear to me what types Agda can erase, and I don't think Agda gives any solid guarantees as to erasure. (As a language aiming for performance, Haskell needs to provide such a guarantee.) Idris does whole-program analysis to determine erasability. I can't imagine this scales well. The choice I've made in the design of Dependent Haskell is to have the user choose whether to keep an argument or not, leading to the forall/foreach distinction. This brings us from 3 quantifiers to 4. In truth, 4 is enough to power dependent types! But read on. All dependently typed languages give a facility for the user to control the visibility of arguments. If we want to do the same, we go from 4 quantifiers to 6. (We don't go to 8 because the original -> and => already differ in visibility.) Note, though, that Coq doesn't consider visibility as a feature of a type, instead using, essentially, pragmas to control visibility. This has some benefits (higher-order usages of functions can't fall over based on visibility), but it doesn't seem well-suited for Haskell. Quite separately, we also will likely want to allow currying in type-level operations. Partially-applied type families are currently forbidden because doing so would wreak havoc with type inference. (Imagine if we're unifying `m a` with `Maybe Int` but that `m` might unify with a type family `Id`!) The solution I've proposed here is a notion of *matchability*, described in Section 4.2.4 of my thesis (which can be read independently of the rest of it). A function is *matchable* iff it is generative and injective -- in other words, if equalities over function applications can be decomposed. When some functions (like Maybe and Either Int) are matchable and some (like Id and any other type family) are not, then type inference can decompose matchable things and not decompose unmatchable things. It turns out that all previous 6 quantifiers are useful in both the matchable and unmatchable varieties, bringing us to 12. Note that other dependently typed languages don't have a notion of matchability. They generally also don't have injective type constructors (you can't derive (a ~ b) from (Maybe a ~ Maybe b)) and don't have the guess-free type inference Haskell has. Instead, those languages generally rely on higher-order unification, which is a best-guess algorithm (as I understand it). GHC has stayed away from guessing. We might imagine a future for GHC that allows partially-applied type functions without using matchability, but I conjecture that any such future would also have to offer weaker guarantees for the predictability and stability of type inference. It might be a fruitful debate to see which is better -- stable type inference or fewer quantifiers. My bottom line: I don't like the 12 quantifiers either. And dependent types require really only 1 new one. Two more come along for the convenience of invisible arguments. And then we have to double for matchability. (Note that matchability can be considered quite orthogonally to dependent types -- it has even been proposed separately in #52.) Perhaps I've overshot in the design here and some healthy debate here can whittle the number down. > * I am not convinced about the utility of the "dependent haskell" extension in the first place. This is the bigger question. Chapter 3 of my thesis lays out some motivation for dependent types, as does Chapter 8 of Adam Gundry's. Historically, every feature (fundeps, type families, GADTs, kind polymorphism, higher-rank types, type applications) that has moved GHC closer to having dependent types has been eagerly adopted. I've heard some push-back over the years about this, but the biggest complaint I've gotten is around termination: people don't want GHC to reject non-terminating functions. When I explain that doing so has never been part of the plan, then generally the objection is retracted. What are the downsides of adding dependent types? - The language becomes more complicated. Haskell already has a reputation of being impossible to learn, and if dependent types appear everywhere, this reputation will be reinforced, to the language's detriment. I am indeed worried about this. Care will have to be taken by library authors to make dependent types an opt-in experience. - Error messages might worsen. I'm actually not terribly worried about this, as I believe clever engineering can avoid it. Other than #11198 (which is now fixed), there has not been a degradation in error messages from -XTypeInType. Errors still use the words "kind" and "type" to mean different things! Even forgetting about dependent types, I think GHC's error messages need an overhaul, basically to become more like Idris's. (That is, interactive.) Especially if we have interactivity in error messages, then there are even more ways to mitigate the potential trouble of dependent types. Note that Haskell's tradition of language extensions help us here: if a user makes a type error in simple code -- but that code might have a meaning in a dependently typed setting -- then we can use the presence or absence of language extensions to tailor the message. (In particular, we might want to be conservative in recommending that the user enable -XDependentTypes.) - The abstraction will sometimes leak. The most glaring example of this is when the type of ($) started muttering about levity polymorphism. That was terrible! I do think that, with care, we can avoid this, by continuing to use compiler flags to tailor output and/or adding interactivity to GHC's output. - The implementation becomes more complicated. Well, yes, though perhaps we'll lose some duplication once GHC no longer has separate Expr and Type types. ----------------------------------------- What to do next? If others on the committee are worried about the desire/utility of dependent types, it might be good to seek input from the community. Beyond that, I'll reiterate 4 possible actions we might take on #102, specifically: 1. Reject the syntax. If we do this, I'd love to open a larger conversation of ways forward -- do we want tweaks to the syntax or a wholly new approach? 2. Put this idea on hold, with a plan to accept or reject #81 on its own merits. 3. Accept the proposal, but put implementation on the back burner. This would serve to reserve the syntax, without burdening our users until the features are more fully-formed. 4. Accept the proposal and plan to implement. Looking forward to seeing your thoughts on this, Richard From mail at joachim-breitner.de Tue Mar 27 05:24:51 2018 From: mail at joachim-breitner.de (Joachim Breitner) Date: Tue, 27 Mar 2018 01:24:51 -0400 Subject: [ghc-steering-committee] Proposal: Binding existential type variables (#96) In-Reply-To: <83DE2F77-F70E-4B7E-8875-CE6BC60CE211@cs.brynmawr.edu> References: <1522074718.24566.7.camel@joachim-breitner.de> <1522088561.24566.36.camel@joachim-breitner.de> <90ADE520-4E5F-4BCA-B11E-2DB89898F01E@cs.brynmawr.edu> <1522089839.24566.44.camel@joachim-breitner.de> <348DA9F2-FAE1-46A5-B57C-FE36EF4B55FA@cs.brynmawr.edu> <83DE2F77-F70E-4B7E-8875-CE6BC60CE211@cs.brynmawr.edu> Message-ID: <1522128291.1067.81.camel@joachim-breitner.de> Hi, I was close to writing “I am not convinced, but if I am the only one who is unhappy with the current proposal, then I will not stand in the way”. But I was away from the computer, so I could not write that, and so I pondered the issue some more, and the more I ponder it, the more dissatisfied with that outcome I am (and it kept me awake tonight…). But I want to be constructive, so I am offering an alternative proposal. Still half-baked, of course, but hopefully already understandable and useful. ### What are the issues? But first allow me to summarize the points of contention, collecting the examples that I brought up before, and adding some new ones. 1. It breaks equational reasoning. data T a where MkT :: forall a b. b -> T a foo (MkT @a y) = E[a :: y] bar = C[foo (MkT @Int True)] is different from bar = C[E[True :: Int]] While we can certainly teach people the difference between @ in expression and @ in patterns, I find this a high price to pay. 2. The distinction between existentials and universals is oddly abrupt. data A a where MkA :: forall a. A a has a universal, but data A' a where MkA' :: forall a. A (Id a) has an extensional. Also, every universal can be turned into an existential, by introducing a new universal. a is universal in A, but existential in data A'' a where MkA'' :: forall a b. a ~ b -> A b although it behaves pretty similar. 3. The intuition “existential = Output” and “universal = Input” is not as straight-forward as it first seems. I see how data B where MkB :: forall a. B has an existential that is unquestionably an output of the pattern match. But what about data B2 where MkB2 :: forall a b. a ~ b -> B now if I pattern match (MkB2 @x @y), then yes, “x” is an output, but “y” somehow less so. Relatedly, if I write data B3 where MkB3 :: forall a. a ~ Int -> B then it’s hardly fair to say that (MkB3 @x) outputs a type “x”. And when we have data B4 a where MkB4 :: forall a b. B (a,b) then writing (MkB4 @x @y) also does not really give us a new types stored in the constructor, but simply deconstructs the type argument of B4. ### Goals of the alternative proposal So is there a way to have our cake and eat it too? A syntax that A. allows us to bind existential variables, B. has consistent syntax in patterns and expressions and C. has the desired property that every variable in a pattern is bound there? Maybe there is. The bullet point 3. above showed that thinking in terms of Input and Output – while very suitable when we talk about the term level – is not quite suitable on the Haskell type level, where information flows in many ways and direction. A better way of working with types is to think of type equalities, unification and matching. And this leads me to ### The alternative proposal (half-baked) Syntax: Constructors in pattern may have type arguments, using the @ syntax from TypeApplication. The type argument correspond to _all_ the universally quantified variables in their type signature. Scoping: Any type variable that occurs in a pattern is brought into scope by this pattern. If a type variable occurs multiple times in the same pattern, then it is the still same variable (no shadowing within a pattern). Semantics: (This part is still a bit vague, if it does not make sense to you, then better skip to the examples.) Consider a constructor C :: forall a b. Ctx[a,b] => T (t2[a,b]) If we use use this in a pattern like so (C @s1 @s2) (used at some type T t) where s1 and s2 are types mentioning the type variables x and y, then this brings x and y into scope. The compiler checks if the constraints from the constructor C', namely (t ~ t2[a,b], Ctx[a,b]) imply that a and b have a shape that can be matched by s1 and s2. If not, then a type error is reported. If yes, then this matching yields instantiations for x and y. Note that this description is completely independent of whether a or b actually occur in t2[a,b]. This means that we can really treat all type arguments of C in a consistent way, without having to put them into two distinct categories. One could summarize this idea as making these two changes to the original proposal: + Every variable is an existential (in that proposal’s lingo) + We allow type patterns in the type applications in patterns, not just single variables. ### Examples Let's see how this variant addresses the dubious examples above. * We now write data T a where MkT :: forall a b. b -> T a foo (MkT @_ @a y) = E[a :: y] bar = C[foo (MkT @Int True)] which makes it clear that @a does not match the @Int, but rather an implicit parameter. If the users chooses to be explicit and writes it as bar = C[foo (MkT @Int @Bool True)] then equational reasoning worksand gives us bar = C[E[True :: Bool]] * The difference between data A a where MkA :: forall a. A a data A' a where MkA' :: forall a. A (Id a) data A'' a where MkA'' :: forall a b. a ~ b -> A b disappears, as all behave identical in pattern matches: foo, foo', foo'' :: A Integer -> () foo (MkA @x) = … here x ~ Integer … foo' (MkA' @x) = … here x ~ Integer … foo'' (MkA'' @x) = … here x ~ Integer … * Looking at data B where MkB :: forall a. B data B2 where MkB2 :: forall a b. a ~ b -> B data B3 where MkB3 :: forall a. a ~ Int -> B data B4 a where MkB4 :: forall a b. B (a,b) we can write foo (MkB @x) = … x is bound … to match the existential, as before, and foo (MkB @(Maybe x)) = would fail, as expected. We can write bar (MkB2 @x @y) = … x and y are in scope, and x~z … just as in the existing proposal, but it would also be legal to write, should one desire to do so, bar (MkB2 @x @x) = With B3 we can match this (fixed) existential, if we want. Or we can assert it’s value: baz (MkB3 @x) = … x in scope, x ~ Int … baz (MkB3 @Int) = … With B4, this everything works just as expected: quux :: B4 ([Bool],()) quux (MkB4 @x @y) = … x and y in scope, x ~ [Bool], y ~ () which, incidentially, is equivalent to the existing quux (MkB4 :: (x, y)) = … x and y in scope, x ~ [Bool], y ~ () and the new syntax also allows quux' (MkB4 @[x]) = … x in scope, x ~ Bool ### A note on scoping Above I wrote “every type variable in a pattern is bound there”. I fear that this will be insufficient when people want to mention a type variable bound further out. So, as a refinement of my proposal, maybe the existing rules for Pattern type signatures (https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/glasgow_exts.html#pattern-type-signatures) should apply: “a pattern type signature may mention a type variable that is not in scope; in this case, the signature brings that type variable into scope” In this variant, all my babbling above can be understood as merely the natural combination of the rules of ScopedTypeVariables (which brought signatures to patterns) and TypeApplications (which can be understood as an alternative syntax for type signatures). What if I really want to introduce a new type variable x, even if x might be in scope? Well, I could imagine syntax for that, where we can list explicitly bound type variables for each function equation. data C a where MkC1 :: forall a, a -> C a MkC2 :: forall b, b -> C Int foo :: forall a. a -> C a -> () foo x c = bar c where bar (MkC1 @a) = … -- matches the a bound by foo with the argument to MkC1 -- which succeeds forall a. bar (MkC2 @a) = x -- introduces a fresh a, bound to MkC2’s existential argument -- and shadowing foo’s type variable a Ok, that ended up quite long. I guess there is a strong risk that I am describing something that Emmanuel, Simon and Richard have already thought through and discarded… if so: why was it discarded? And if not: does this proposal have merits? Cheers and good night, Joachim PS: Happy 3rd anniversary to GHC-7.10 :-) -- Joachim Breitner mail at joachim-breitner.de http://www.joachim-breitner.de/ -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 833 bytes Desc: This is a digitally signed message part URL: From simonpj at microsoft.com Tue Mar 27 21:53:26 2018 From: simonpj at microsoft.com (Simon Peyton Jones) Date: Tue, 27 Mar 2018 21:53:26 +0000 Subject: [ghc-steering-committee] Proposal: Binding existential type variables (#96) In-Reply-To: <83DE2F77-F70E-4B7E-8875-CE6BC60CE211@cs.brynmawr.edu> References: <1522074718.24566.7.camel@joachim-breitner.de> <1522088561.24566.36.camel@joachim-breitner.de> <90ADE520-4E5F-4BCA-B11E-2DB89898F01E@cs.brynmawr.edu> <1522089839.24566.44.camel@joachim-breitner.de> <348DA9F2-FAE1-46A5-B57C-FE36EF4B55FA@cs.brynmawr.edu> <83DE2F77-F70E-4B7E-8875-CE6BC60CE211@cs.brynmawr.edu> Message-ID: Yes I like the "\" too. (Or some syntax separating inputs from outputs.) More specifically, I really like the possibility of specifying input values to a pattern. You can do that with view patterns - but you can't abstract over those view patterns with a pattern synonym (currently). It'd be great to be able to say pattern P n \ x <- ((\y -> if y>2*n+1 then Just y else Nothing) -> Just x) This looks pretty impenetrable, but it's using a view pattern to test if the argument is > 2n+1, and match if so. So 'n' is an input, and x is an output. I think we have to group all the inputs together and have a separator. No inter-mingling. Remember, we want the distinction to be syntactically obvious; and outputs must be variables while inputs can be arbitrary terms or types. As discussed earlier, for inputs, @ distinguishes types from terms; for outputs, @ distinguishes type binder from term binders. Simon From: ghc-steering-committee On Behalf Of Richard Eisenberg Sent: 27 March 2018 03:47 To: Roman Leshchinskiy Cc: ghc-steering-committee at haskell.org; Joachim Breitner Subject: Re: [ghc-steering-committee] Proposal: Binding existential type variables (#96) On Mar 26, 2018, at 5:54 PM, Roman Leshchinskiy > wrote: C \ I had been trying to figure out how to get \ involved, and this is the way. Thanks! It does require that all inputs come before all outputs, which might not be true for constructors: data T a where MkT :: forall b a. b -> T a Here, `b` is an output while `a` would be an input. And in many cases constructors designed with visible type application in mind will want to put existentials ("outputs") before universals ("inputs"). If we ever did the C \ in the future, I suppose we could just say that such constructors will have their type variables reordered, perhaps issuing a warning if someone writes a mis-ordered constructor. In any case, I'm glad that this discussion has changed your mind about accepting this proposal. Thanks, Richard -------------- next part -------------- An HTML attachment was scrubbed... URL: From simonpj at microsoft.com Tue Mar 27 21:53:28 2018 From: simonpj at microsoft.com (Simon Peyton Jones) Date: Tue, 27 Mar 2018 21:53:28 +0000 Subject: [ghc-steering-committee] Proposal: Binding existential type variables (#96) In-Reply-To: <1522128291.1067.81.camel@joachim-breitner.de> References: <1522074718.24566.7.camel@joachim-breitner.de> <1522088561.24566.36.camel@joachim-breitner.de> <90ADE520-4E5F-4BCA-B11E-2DB89898F01E@cs.brynmawr.edu> <1522089839.24566.44.camel@joachim-breitner.de> <348DA9F2-FAE1-46A5-B57C-FE36EF4B55FA@cs.brynmawr.edu> <83DE2F77-F70E-4B7E-8875-CE6BC60CE211@cs.brynmawr.edu> <1522128291.1067.81.camel@joachim-breitner.de> Message-ID: Interesting idea from Joachim. But it's quite complicated. Here is a much simpler version. Consider data T a where MkT :: forall a b. a -> b -> T a Suppose we said that - In pattern you must list a type binder for every forall, whether universal or existential. Thus a pattern with explicit type binders would look like MkT @x @y p q f :: T Int -> Int f (MkT @x @y (p::x) (q::y)) = x - In a pattern (MkT @x @y p q) x and y are both brought into scope by the pattern, and must be variables (not types). (In contrast, p and q can be patterns.) - For universals, you implicitly get an equality that connects the binder to the type of the scrutinee. So in the above example f :: T Int -> Int f (MkT @x @y (p::x) (q::y)) = x we would have an implicit equality x~Int, which is why the RHS (which must return an Int) is well typed. It's much as if we had declared MkT with two existentials MkT :: forall a b c. (a~c) => a -> b -> T c This is a bit simpler than what Joachim suggests, but I think it meets his key goal: that a MkT pattern has the same number of type args as a MkT term. I had not previously thought of this, but it removes most of my objections: here 'x' really is brought into scope, just with an accompanying equality. And it is fairly simple to explain. Hmm. Do others like this? If so we could go back to the proposer with this as a suggestion. Simon | -----Original Message----- | From: ghc-steering-committee On Behalf Of Joachim Breitner | Sent: 27 March 2018 06:25 | To: ghc-steering-committee at haskell.org | Subject: Re: [ghc-steering-committee] Proposal: Binding existential type | variables (#96) | | Hi, | | I was close to writing “I am not convinced, but if I am the only one | who is unhappy with the current proposal, then I will not stand in the | way”. But I was away from the computer, so I could not write that, and | so I pondered the issue some more, and the more I ponder it, the more | dissatisfied with that outcome I am (and it kept me awake tonight…). | | But I want to be constructive, so I am offering an alternative | proposal. Still half-baked, of course, but hopefully already | understandable and useful. | | ### What are the issues? | | But first allow me to summarize the points of contention, collecting | the examples that I brought up before, and adding some new ones. | | 1. It breaks equational reasoning. | | data T a where MkT :: forall a b. b -> T a | foo (MkT @a y) = E[a :: y] | bar = C[foo (MkT @Int True)] | | is different from | | bar = C[E[True :: Int]] | | While we can certainly teach people the difference between @ in | expression and @ in patterns, I find this a high price to pay. | | 2. The distinction between existentials and universals is oddly abrupt. | | data A a where MkA :: forall a. A a | | has a universal, but | | data A' a where MkA' :: forall a. A (Id a) | | has an extensional. | | Also, every universal can be turned into an existential, by | introducing a new universal. a is universal in A, but existential in | | | data A'' a where MkA'' :: forall a b. a ~ b -> A b | | although it behaves pretty similar. | | 3. The intuition “existential = Output” and “universal = Input” is | not as straight-forward as it first seems. I see how | | data B where MkB :: forall a. B | | has an existential that is unquestionably an output of the pattern | match. But what about | | data B2 where MkB2 :: forall a b. a ~ b -> B | | now if I pattern match (MkB2 @x @y), then yes, “x” is an output, | but “y” somehow less so. Relatedly, if I write | | data B3 where MkB3 :: forall a. a ~ Int -> B | | then it’s hardly fair to say that (MkB3 @x) outputs a type “x”. And | when we have | | data B4 a where MkB4 :: forall a b. B (a,b) | | then writing (MkB4 @x @y) also does not really give us a new types | stored in the constructor, but simply deconstructs the type argument | of B4. | | ### Goals of the alternative proposal | | So is there a way to have our cake and eat it too? A syntax that | A. allows us to bind existential variables, | B. has consistent syntax in patterns and expressions and | C. has the desired property that every variable in a pattern is bound | there? | | Maybe there is. The bullet point 3. above showed that thinking in terms | of Input and Output – while very suitable when we talk about the term | level – is not quite suitable on the Haskell type level, where | information flows in many ways and direction. | | A better way of working with types is to think of type equalities, | unification and matching. And this leads me to | | ### The alternative proposal (half-baked) | | Syntax: | Constructors in pattern may have type arguments, using the @ syntax | from TypeApplication. The type argument correspond to _all_ the | universally quantified variables in their type signature. | | Scoping: | Any type variable that occurs in a pattern is brought into scope by | this pattern. If a type variable occurs multiple times in the same | pattern, then it is the still same variable (no shadowing within a | pattern). | | Semantics: | (This part is still a bit vague, if it does not make sense to you, then | better skip to the examples.) | Consider a constructor | | C :: forall a b. Ctx[a,b] => T (t2[a,b]) | | If we use use this in a pattern like so | | (C @s1 @s2) (used at some type T t) | | where s1 and s2 are types mentioning the type variables x and y, then | this brings x and y into scope. The compiler checks if the constraints | from the constructor C', namely | (t ~ t2[a,b], Ctx[a,b]) | imply that a and b have a shape that can be matched by s1 and s2. | If not, then a type error is reported. | If yes, then this matching yields instantiations for x and y. | | Note that this description is completely independent of whether a or b | actually occur in t2[a,b]. This means that we can really treat all type | arguments of C in a consistent way, without having to put them into two | distinct categories. | | One could summarize this idea as making these two changes to the | original proposal: | + Every variable is an existential (in that proposal’s lingo) | + We allow type patterns in the type applications in patterns, not | just single variables. | | | ### Examples | | Let's see how this variant addresses the dubious examples above. | | * We now write | | data T a where MkT :: forall a b. b -> T a | foo (MkT @_ @a y) = E[a :: y] | bar = C[foo (MkT @Int True)] | | which makes it clear that @a does not match the @Int, but rather an | implicit parameter. If the users chooses to be explicit and writes | it as | bar = C[foo (MkT @Int @Bool True)] | then equational reasoning worksand gives us | bar = C[E[True :: Bool]] | | * The difference between | | data A a where MkA :: forall a. A a | data A' a where MkA' :: forall a. A (Id a) | data A'' a where MkA'' :: forall a b. a ~ b -> A b | | disappears, as all behave identical in pattern matches: | | foo, foo', foo'' :: A Integer -> () | foo (MkA @x) = … here x ~ Integer … | foo' (MkA' @x) = … here x ~ Integer … | foo'' (MkA'' @x) = … here x ~ Integer … | | * Looking at | | data B where MkB :: forall a. B | data B2 where MkB2 :: forall a b. a ~ b -> B | data B3 where MkB3 :: forall a. a ~ Int -> B | data B4 a where MkB4 :: forall a b. B (a,b) | | we can write | | foo (MkB @x) = … x is bound … | | to match the existential, as before, and | | foo (MkB @(Maybe x)) = | | would fail, as expected. We can write | | bar (MkB2 @x @y) = … x and y are in scope, and x~z … | | just as in the existing proposal, but it would also be legal to | write, should one desire to do so, | | bar (MkB2 @x @x) = | | With B3 we can match this (fixed) existential, if we want. Or we | can | assert it’s value: | | baz (MkB3 @x) = … x in scope, x ~ Int … | baz (MkB3 @Int) = … | | With B4, this everything works just as expected: | | quux :: B4 ([Bool],()) | quux (MkB4 @x @y) = … x and y in scope, x ~ [Bool], y ~ () | | which, incidentially, is equivalent to the existing | | quux (MkB4 :: (x, y)) = … x and y in scope, x ~ [Bool], y ~ () | | and the new syntax also allows | | quux' (MkB4 @[x]) = … x in scope, x ~ Bool | | | ### A note on scoping | | Above I wrote “every type variable in a pattern is bound there”. I fear | that this will be insufficient when people want to mention a type | variable bound further out. So, as a refinement of my proposal, maybe | the existing rules for Pattern type signatures | (https://na01.safelinks.protection.outlook.com/?url=https:%2F%2Fdownload | s.haskell.org%2F~ghc%2Flatest%2Fdocs%2Fhtml%2Fusers_guide%2Fglasgow_exts | .html%23pattern-type- | signatures&data=02%7C01%7Csimonpj%40microsoft.com%7C1b42c7e570c94b8d26e1 | 08d593a31aad%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C63657725109818 | 1218&sdata=G3twWyxN9UkQ%2Bs3vBOiNxj4NfZCOty24nk3lbXV5WNI%3D&reserved=0) | should apply: “a pattern type signature may mention a type variable | that is not in scope; in this case, the signature brings that type | variable into scope” | | In this variant, all my babbling above can be understood as merely the | natural combination of the rules of ScopedTypeVariables (which brought | signatures to patterns) and TypeApplications (which can be understood | as an alternative syntax for type signatures). | | What if I really want to introduce a new type variable x, even if x | might be in scope? Well, I could imagine syntax for that, where we can | list explicitly bound type variables for each function equation. | | data C a where MkC1 :: forall a, a -> C a | MkC2 :: forall b, b -> C Int | | foo :: forall a. a -> C a -> () | foo x c = bar c | where | bar (MkC1 @a) = … | -- matches the a bound by foo with the argument to MkC1 | -- which succeeds | forall a. bar (MkC2 @a) = x | -- introduces a fresh a, bound to MkC2’s existential argument | -- and shadowing foo’s type variable a | | | | Ok, that ended up quite long. I guess there is a strong risk that I am | describing something that Emmanuel, Simon and Richard have already | thought through and discarded… if so: why was it discarded? And if not: | does this proposal have merits? | | Cheers and good night, | Joachim | | PS: Happy 3rd anniversary to GHC-7.10 :-) | | | -- | Joachim Breitner | mail at joachim-breitner.de | | https://na01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fwww.joac | him- | breitner.de%2F&data=02%7C01%7Csimonpj%40microsoft.com%7C1b42c7e570c94b8d | 26e108d593a31aad%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C6365772510 | 98181218&sdata=bl1ob%2FZWifjoMkgXXMRVjnTbn0RS1588ZCf4Cw7Juw0%3D&reserved | =0 From simonpj at microsoft.com Tue Mar 27 22:11:00 2018 From: simonpj at microsoft.com (Simon Peyton Jones) Date: Tue, 27 Mar 2018 22:11:00 +0000 Subject: [ghc-steering-committee] DH quantifiers (#102), Recommendation: accept In-Reply-To: <32A4865D-5D1A-4B90-9FD3-7BB1356E0626@cs.brynmawr.edu> References: <1519400339.28221.25.camel@joachim-breitner.de> <32A4865D-5D1A-4B90-9FD3-7BB1356E0626@cs.brynmawr.edu> Message-ID: I'm on a train, and don't have access to the proposals, but here's are some thoughts: * #54 is about letting users write kind signatures for type constructors, just as they can write type signatures for term variables. It's amazing we have lasted so long without this ability, but it's really really hurting us. I feel strongly that we should fix this: we need SOME way to write a kind signature for a type constructor. * To write such a kind signature we need something like the T :: forall a b -> blah syntax, to indicate which of T's arguments should be written positionally (like the Int in Proxy Int) and which are hidden (like the * in Proxy Int). By hook or by crook we must be able to express this. And that's #81. * The worry with #81 was whether it would be painting us into a corner. Hence #102. But I regard #102 as an existence proof that the corner has an exit, not as something we should espouse now. (Tell me if you disagree Richard.) It is far off our radar, and premature to make a commitment. Richard: you could add the analysis in your email about "why 12" to the proposal. So I suggest that we accept #54 and #81, and simply punt on #102. Simon | -----Original Message----- | From: ghc-steering-committee On Behalf Of Richard Eisenberg | Sent: 27 March 2018 04:36 | To: Iavor Diatchki | Cc: ghc-steering-committee at haskell.org; Joachim Breitner | Subject: Re: [ghc-steering-committee] DH quantifiers (#102), | Recommendation: accept | | I'd like to restart this thread, both as the Grand Poobah of Dependent | Haskell and because Proposal #102 (this one) is holding up #81 (the | `forall x y z ->` syntax), which is, in turn, holding up #54 (a plan to | eliminate the need for CUSKs), which is implicated in quite a few bugs. | | I think Iavor makes some good criticisms below, which I'll address | individually: | | > On Feb 23, 2018, at 12:12 PM, Iavor Diatchki | wrote: | > | > * it is premature to "reserve" syntax for a future extension | | This is a hard one. The full implementation of dependent types in | Haskell is still years away. But decisions we make now may affect the | eventual concrete syntax. While a ghc-proposal is ill-fitted with | reserving syntax, I think Roman was right to request that #81 be | considered in the context of the larger syntactic changes. Maybe the | "right" answer here is for the committee to conclude that the proposed | syntax is generally plausible, paving the way for #81 but without making | a solid commitment. On the other hand, if we can identify a better | syntax for the overall design of dependent types in Haskell, that might | affect the syntax used in #81/#54. | | > * I am not convinced that a design with 12 quantifiers is what I'd | want to use | | Neither am I! | | For a moment, let's take the desire for dependent types to be a given. | (I'll address this more below.) GHC currently has 3 quantifiers (`forall | a.`, `ty ->`, and `ty =>`). To preserve type erasure, we need to | distinguish between arguments needed at runtime and those that can be | erased. | | Coq does this through its Set-vs-Prop mechanism, where erased arguments | live in their own sort. Such a route is viable for Haskell, I think, but | I've never been much enamored of it, personally. For example, the Nat in | a vector type really can be erased, while Nats in many other places | can't be, and it seems a shame to need two different Nat types to pull | off this dichotomy. | | Agda uses the term "irrelevant" to describe type indices that are | ignored during type equality checks. This is related to the type erasure | property, but it's not quite the same thing. It's unclear to me what | types Agda can erase, and I don't think Agda gives any solid guarantees | as to erasure. (As a language aiming for performance, Haskell needs to | provide such a guarantee.) | | Idris does whole-program analysis to determine erasability. I can't | imagine this scales well. | | The choice I've made in the design of Dependent Haskell is to have the | user choose whether to keep an argument or not, leading to the | forall/foreach distinction. This brings us from 3 quantifiers to 4. In | truth, 4 is enough to power dependent types! But read on. | | All dependently typed languages give a facility for the user to control | the visibility of arguments. If we want to do the same, we go from 4 | quantifiers to 6. (We don't go to 8 because the original -> and => | already differ in visibility.) Note, though, that Coq doesn't consider | visibility as a feature of a type, instead using, essentially, pragmas | to control visibility. This has some benefits (higher-order usages of | functions can't fall over based on visibility), but it doesn't seem | well-suited for Haskell. | | Quite separately, we also will likely want to allow currying in type- | level operations. Partially-applied type families are currently | forbidden because doing so would wreak havoc with type inference. | (Imagine if we're unifying `m a` with `Maybe Int` but that `m` might | unify with a type family `Id`!) The solution I've proposed here is a | notion of *matchability*, described in Section 4.2.4 of my thesis (which | can be read independently of the rest of it). A function is *matchable* | iff it is generative and injective -- in other words, if equalities over | function applications can be decomposed. When some functions (like Maybe | and Either Int) are matchable and some (like Id and any other type | family) are not, then type inference can decompose matchable things and | not decompose unmatchable things. It turns out that all previous 6 | quantifiers are useful in both the matchable and unmatchable varieties, | bringing us to 12. | | Note that other dependently typed languages don't have a notion of | matchability. They generally also don't have injective type constructors | (you can't derive (a ~ b) from (Maybe a ~ Maybe b)) and don't have the | guess-free type inference Haskell has. Instead, those languages | generally rely on higher-order unification, which is a best-guess | algorithm (as I understand it). GHC has stayed away from guessing. We | might imagine a future for GHC that allows partially-applied type | functions without using matchability, but I conjecture that any such | future would also have to offer weaker guarantees for the predictability | and stability of type inference. It might be a fruitful debate to see | which is better -- stable type inference or fewer quantifiers. | | My bottom line: I don't like the 12 quantifiers either. And dependent | types require really only 1 new one. Two more come along for the | convenience of invisible arguments. And then we have to double for | matchability. (Note that matchability can be considered quite | orthogonally to dependent types -- it has even been proposed separately | in #52.) Perhaps I've overshot in the design here and some healthy | debate here can whittle the number down. | | > * I am not convinced about the utility of the "dependent haskell" | extension in the first place. | | This is the bigger question. Chapter 3 of my thesis lays out some | motivation for dependent types, as does Chapter 8 of Adam Gundry's. | Historically, every feature (fundeps, type families, GADTs, kind | polymorphism, higher-rank types, type applications) that has moved GHC | closer to having dependent types has been eagerly adopted. I've heard | some push-back over the years about this, but the biggest complaint I've | gotten is around termination: people don't want GHC to reject non- | terminating functions. When I explain that doing so has never been part | of the plan, then generally the objection is retracted. | | What are the downsides of adding dependent types? | | - The language becomes more complicated. Haskell already has a | reputation of being impossible to learn, and if dependent types appear | everywhere, this reputation will be reinforced, to the language's | detriment. I am indeed worried about this. Care will have to be taken by | library authors to make dependent types an opt-in experience. | | - Error messages might worsen. I'm actually not terribly worried about | this, as I believe clever engineering can avoid it. Other than #11198 | (which is now fixed), there has not been a degradation in error messages | from -XTypeInType. Errors still use the words "kind" and "type" to mean | different things! Even forgetting about dependent types, I think GHC's | error messages need an overhaul, basically to become more like Idris's. | (That is, interactive.) Especially if we have interactivity in error | messages, then there are even more ways to mitigate the potential | trouble of dependent types. Note that Haskell's tradition of language | extensions help us here: if a user makes a type error in simple code -- | but that code might have a meaning in a dependently typed setting -- | then we can use the presence or absence of language extensions to tailor | the message. (In particular, we might want to be conservative in | recommending that the user enable -XDependentTypes.) | | - The abstraction will sometimes leak. The most glaring example of this | is when the type of ($) started muttering about levity polymorphism. | That was terrible! I do think that, with care, we can avoid this, by | continuing to use compiler flags to tailor output and/or adding | interactivity to GHC's output. | | - The implementation becomes more complicated. Well, yes, though perhaps | we'll lose some duplication once GHC no longer has separate Expr and | Type types. | | ----------------------------------------- | | What to do next? If others on the committee are worried about the | desire/utility of dependent types, it might be good to seek input from | the community. Beyond that, I'll reiterate 4 possible actions we might | take on #102, specifically: | | 1. Reject the syntax. If we do this, I'd love to open a larger | conversation of ways forward -- do we want tweaks to the syntax or a | wholly new approach? | | 2. Put this idea on hold, with a plan to accept or reject #81 on its own | merits. | | 3. Accept the proposal, but put implementation on the back burner. This | would serve to reserve the syntax, without burdening our users until the | features are more fully-formed. | | 4. Accept the proposal and plan to implement. | | Looking forward to seeing your thoughts on this, | Richard | _______________________________________________ | ghc-steering-committee mailing list | ghc-steering-committee at haskell.org | https://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-steering-committee From chak at justtesting.org Tue Mar 27 22:50:22 2018 From: chak at justtesting.org (Manuel M T Chakravarty) Date: Wed, 28 Mar 2018 09:50:22 +1100 Subject: [ghc-steering-committee] Proposal: Binding existential type variables (#96) In-Reply-To: <1522128291.1067.81.camel@joachim-breitner.de> References: <1522074718.24566.7.camel@joachim-breitner.de> <1522088561.24566.36.camel@joachim-breitner.de> <90ADE520-4E5F-4BCA-B11E-2DB89898F01E@cs.brynmawr.edu> <1522089839.24566.44.camel@joachim-breitner.de> <348DA9F2-FAE1-46A5-B57C-FE36EF4B55FA@cs.brynmawr.edu> <83DE2F77-F70E-4B7E-8875-CE6BC60CE211@cs.brynmawr.edu> <1522128291.1067.81.camel@joachim-breitner.de> Message-ID: I can’t say that I am sure of the details, but Joachim’s proposal seems appealing to me. Manuel > Am 27.03.2018 um 16:24 schrieb Joachim Breitner : > > Hi, > > I was close to writing “I am not convinced, but if I am the only one > who is unhappy with the current proposal, then I will not stand in the > way”. But I was away from the computer, so I could not write that, and > so I pondered the issue some more, and the more I ponder it, the more > dissatisfied with that outcome I am (and it kept me awake tonight…). > > But I want to be constructive, so I am offering an alternative > proposal. Still half-baked, of course, but hopefully already > understandable and useful. > > ### What are the issues? > > But first allow me to summarize the points of contention, collecting > the examples that I brought up before, and adding some new ones. > > 1. It breaks equational reasoning. > > data T a where MkT :: forall a b. b -> T a > foo (MkT @a y) = E[a :: y] > bar = C[foo (MkT @Int True)] > > is different from > > bar = C[E[True :: Int]] > > While we can certainly teach people the difference between @ in > expression and @ in patterns, I find this a high price to pay. > > 2. The distinction between existentials and universals is oddly abrupt. > > data A a where MkA :: forall a. A a > > has a universal, but > > data A' a where MkA' :: forall a. A (Id a) > > has an extensional. > > Also, every universal can be turned into an existential, by > introducing a new universal. a is universal in A, but existential in > > > data A'' a where MkA'' :: forall a b. a ~ b -> A b > > although it behaves pretty similar. > > 3. The intuition “existential = Output” and “universal = Input” is > not as straight-forward as it first seems. I see how > > data B where MkB :: forall a. B > > has an existential that is unquestionably an output of the pattern > match. But what about > > data B2 where MkB2 :: forall a b. a ~ b -> B > > now if I pattern match (MkB2 @x @y), then yes, “x” is an output, > but “y” somehow less so. Relatedly, if I write > > data B3 where MkB3 :: forall a. a ~ Int -> B > > then it’s hardly fair to say that (MkB3 @x) outputs a type “x”. And > when we have > > data B4 a where MkB4 :: forall a b. B (a,b) > > then writing (MkB4 @x @y) also does not really give us a new types > stored in the constructor, but simply deconstructs the type argument > of B4. > > ### Goals of the alternative proposal > > So is there a way to have our cake and eat it too? A syntax that > A. allows us to bind existential variables, > B. has consistent syntax in patterns and expressions and > C. has the desired property that every variable in a pattern is bound > there? > > Maybe there is. The bullet point 3. above showed that thinking in terms > of Input and Output – while very suitable when we talk about the term > level – is not quite suitable on the Haskell type level, where > information flows in many ways and direction. > > A better way of working with types is to think of type equalities, > unification and matching. And this leads me to > > ### The alternative proposal (half-baked) > > Syntax: > Constructors in pattern may have type arguments, using the @ syntax > from TypeApplication. The type argument correspond to _all_ the > universally quantified variables in their type signature. > > Scoping: > Any type variable that occurs in a pattern is brought into scope by > this pattern. If a type variable occurs multiple times in the same > pattern, then it is the still same variable (no shadowing within a > pattern). > > Semantics: > (This part is still a bit vague, if it does not make sense to you, then > better skip to the examples.) > Consider a constructor > > C :: forall a b. Ctx[a,b] => T (t2[a,b]) > > If we use use this in a pattern like so > > (C @s1 @s2) (used at some type T t) > > where s1 and s2 are types mentioning the type variables x and y, then > this brings x and y into scope. The compiler checks if the constraints > from the constructor C', namely > (t ~ t2[a,b], Ctx[a,b]) > imply that a and b have a shape that can be matched by s1 and s2. > If not, then a type error is reported. > If yes, then this matching yields instantiations for x and y. > > Note that this description is completely independent of whether a or b > actually occur in t2[a,b]. This means that we can really treat all type > arguments of C in a consistent way, without having to put them into two > distinct categories. > > One could summarize this idea as making these two changes to the > original proposal: > + Every variable is an existential (in that proposal’s lingo) > + We allow type patterns in the type applications in patterns, not > just single variables. > > > ### Examples > > Let's see how this variant addresses the dubious examples above. > > * We now write > > data T a where MkT :: forall a b. b -> T a > foo (MkT @_ @a y) = E[a :: y] > bar = C[foo (MkT @Int True)] > > which makes it clear that @a does not match the @Int, but rather an > implicit parameter. If the users chooses to be explicit and writes > it as > bar = C[foo (MkT @Int @Bool True)] > then equational reasoning worksand gives us > bar = C[E[True :: Bool]] > > * The difference between > > data A a where MkA :: forall a. A a > data A' a where MkA' :: forall a. A (Id a) > data A'' a where MkA'' :: forall a b. a ~ b -> A b > > disappears, as all behave identical in pattern matches: > > foo, foo', foo'' :: A Integer -> () > foo (MkA @x) = … here x ~ Integer … > foo' (MkA' @x) = … here x ~ Integer … > foo'' (MkA'' @x) = … here x ~ Integer … > > * Looking at > > data B where MkB :: forall a. B > data B2 where MkB2 :: forall a b. a ~ b -> B > data B3 where MkB3 :: forall a. a ~ Int -> B > data B4 a where MkB4 :: forall a b. B (a,b) > > we can write > > foo (MkB @x) = … x is bound … > > to match the existential, as before, and > > foo (MkB @(Maybe x)) = > > would fail, as expected. We can write > > bar (MkB2 @x @y) = … x and y are in scope, and x~z … > > just as in the existing proposal, but it would also be legal to > write, should one desire to do so, > > bar (MkB2 @x @x) = > > With B3 we can match this (fixed) existential, if we want. Or we > can > assert it’s value: > > baz (MkB3 @x) = … x in scope, x ~ Int … > baz (MkB3 @Int) = … > > With B4, this everything works just as expected: > > quux :: B4 ([Bool],()) > quux (MkB4 @x @y) = … x and y in scope, x ~ [Bool], y ~ () > > which, incidentially, is equivalent to the existing > > quux (MkB4 :: (x, y)) = … x and y in scope, x ~ [Bool], y ~ () > > and the new syntax also allows > > quux' (MkB4 @[x]) = … x in scope, x ~ Bool > > > ### A note on scoping > > Above I wrote “every type variable in a pattern is bound there”. I fear > that this will be insufficient when people want to mention a type > variable bound further out. So, as a refinement of my proposal, maybe > the existing rules for Pattern type signatures > (https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/glasgow_exts.html#pattern-type-signatures) > should apply: “a pattern type signature may mention a type variable > that is not in scope; in this case, the signature brings that type > variable into scope” > > In this variant, all my babbling above can be understood as merely the > natural combination of the rules of ScopedTypeVariables (which brought > signatures to patterns) and TypeApplications (which can be understood > as an alternative syntax for type signatures). > > What if I really want to introduce a new type variable x, even if x > might be in scope? Well, I could imagine syntax for that, where we can > list explicitly bound type variables for each function equation. > > data C a where MkC1 :: forall a, a -> C a > MkC2 :: forall b, b -> C Int > > foo :: forall a. a -> C a -> () > foo x c = bar c > where > bar (MkC1 @a) = … > -- matches the a bound by foo with the argument to MkC1 > -- which succeeds > forall a. bar (MkC2 @a) = x > -- introduces a fresh a, bound to MkC2’s existential argument > -- and shadowing foo’s type variable a > > > > Ok, that ended up quite long. I guess there is a strong risk that I am > describing something that Emmanuel, Simon and Richard have already > thought through and discarded… if so: why was it discarded? And if not: > does this proposal have merits? > > Cheers and good night, > Joachim > > PS: Happy 3rd anniversary to GHC-7.10 :-) > > > -- > 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 -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 874 bytes Desc: Message signed with OpenPGP URL: From mail at joachim-breitner.de Wed Mar 28 15:26:29 2018 From: mail at joachim-breitner.de (Joachim Breitner) Date: Wed, 28 Mar 2018 11:26:29 -0400 Subject: [ghc-steering-committee] Proposal: Binding existential type variables (#96) In-Reply-To: References: <1522074718.24566.7.camel@joachim-breitner.de> <1522088561.24566.36.camel@joachim-breitner.de> <90ADE520-4E5F-4BCA-B11E-2DB89898F01E@cs.brynmawr.edu> <1522089839.24566.44.camel@joachim-breitner.de> <348DA9F2-FAE1-46A5-B57C-FE36EF4B55FA@cs.brynmawr.edu> <83DE2F77-F70E-4B7E-8875-CE6BC60CE211@cs.brynmawr.edu> <1522128291.1067.81.camel@joachim-breitner.de> Message-ID: <1522250789.11597.11.camel@joachim-breitner.de> Hi, Am Dienstag, den 27.03.2018, 21:53 +0000 schrieb Simon Peyton Jones: > Interesting idea from Joachim. But it's quite complicated. > Here is a much simpler version. great! I like it: It is no less expressive than the original proposal, but forward-compatible to the full version of my proposal (which allows types, not just type variables). I believe we will want the full version eventually (Both to say `foo (Nothing @Int) = …` and once we have matchable implicit argument – right, Richard?), but we don’t have to do both steps at once. May I add one constraint to the simpler alternative proposal: It is an error to @-bind a type variables that would shadow type variable that is already in scope (whether from ScopedTypeVariables, from an instance head or from a @-binder). Why? Well, for forward compatibility. But also for consistency! To our users (or, at least to me) these two expressions are different ways of writing the same things: foo1, foo1' :: forall a. a -> Int foo1 x = length (Nothing :: Maybe a) foo1' x = length (Nothing @ a) I.e. TypeApplication is just a more convenient alternative to type signatures. The same is true, in patterns, under your simplified alternative proposal: foo2, foo2' :: a -> Maybe Int -> Int foo2 _ (Nothing :: Maybe a) = 42 foo2' _ (Nothing @ a) = 42 In both forms, a is bound by the pattern (and `a ~ Int` is added to the context). But note that a change somewhere else (and it could be arbitrarily far away if `foo2` is a local function) breaks the symmetry, at least with ScopedTypeVariables enabled: foo3, foo3' :: forall a. a -> Maybe Int -> Int foo3 _ (Nothing :: Maybe a) = 42 -- type error (a ≠ Int) foo3' _ (Nothing @ a) = 42 -- shadows a Hence I would ask to simply forbid the latter form in the simplified version of the proposal. This * helps the user not shooting in his own leg and * is compatible with the full proposal, where foo3 and foo3' would be equivalent. Cheers, Joachim -- Joachim Breitner mail at joachim-breitner.de http://www.joachim-breitner.de/ -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 833 bytes Desc: This is a digitally signed message part URL: From rleshchinskiy at gmail.com Wed Mar 28 15:37:36 2018 From: rleshchinskiy at gmail.com (Roman Leshchinskiy) Date: Wed, 28 Mar 2018 16:37:36 +0100 Subject: [ghc-steering-committee] Proposal: Binding existential type variables (#96) In-Reply-To: <1522128291.1067.81.camel@joachim-breitner.de> References: <1522074718.24566.7.camel@joachim-breitner.de> <1522088561.24566.36.camel@joachim-breitner.de> <90ADE520-4E5F-4BCA-B11E-2DB89898F01E@cs.brynmawr.edu> <1522089839.24566.44.camel@joachim-breitner.de> <348DA9F2-FAE1-46A5-B57C-FE36EF4B55FA@cs.brynmawr.edu> <83DE2F77-F70E-4B7E-8875-CE6BC60CE211@cs.brynmawr.edu> <1522128291.1067.81.camel@joachim-breitner.de> Message-ID: On Tue, Mar 27, 2018 at 6:24 AM, Joachim Breitner wrote: > > 2. The distinction between existentials and universals is oddly abrupt. > This is a good point. In addition to what Joachim said, universals can also depend on existentials which I find weird. As an aside, here is one corner case which I don't think is handled in the proposal: data T a where MkT :: forall a. T a With -XPolyKinds, the type inferred for T is forall k (a :: k). T a. Now, k is an existential but can it be bound in a pattern? The proposal only mentions 2 cases: no forall and a forall that mentions all type variables and neither applies here. Roman -------------- next part -------------- An HTML attachment was scrubbed... URL: From mail at joachim-breitner.de Wed Mar 28 15:42:37 2018 From: mail at joachim-breitner.de (Joachim Breitner) Date: Wed, 28 Mar 2018 11:42:37 -0400 Subject: [ghc-steering-committee] Proposal: Binding existential type variables (#96) In-Reply-To: References: <1522074718.24566.7.camel@joachim-breitner.de> <1522088561.24566.36.camel@joachim-breitner.de> <90ADE520-4E5F-4BCA-B11E-2DB89898F01E@cs.brynmawr.edu> <1522089839.24566.44.camel@joachim-breitner.de> <348DA9F2-FAE1-46A5-B57C-FE36EF4B55FA@cs.brynmawr.edu> <83DE2F77-F70E-4B7E-8875-CE6BC60CE211@cs.brynmawr.edu> <1522128291.1067.81.camel@joachim-breitner.de> Message-ID: <1522251757.11597.15.camel@joachim-breitner.de> Hi, Am Mittwoch, den 28.03.2018, 16:37 +0100 schrieb Roman Leshchinskiy: > On Tue, Mar 27, 2018 at 6:24 AM, Joachim Breitner wrote: > > 2. The distinction between existentials and universals is oddly abrupt. > > This is a good point. In addition to what Joachim said, universals > can also depend on existentials which I find weird. > > As an aside, here is one corner case which I don't think is handled > in the proposal: > > data T a where > MkT :: forall a. T a > > With -XPolyKinds, the type inferred for T is forall k (a :: k). T a. > Now, k is an existential but can it be bound in a pattern? The > proposal only mentions 2 cases: no forall and a forall that mentions > all type variables and neither applies here. good point – the future of this should be addressed by https://github.com/ghc-proposals/ghc-proposals/pull/103 but it would be clear to be explicit in how this will be handled in #96 until #103 is fully in place. Cheers, Joachim -- Joachim Breitner mail at joachim-breitner.de http://www.joachim-breitner.de/ -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 833 bytes Desc: This is a digitally signed message part URL: From rae at cs.brynmawr.edu Wed Mar 28 16:26:10 2018 From: rae at cs.brynmawr.edu (Richard Eisenberg) Date: Wed, 28 Mar 2018 12:26:10 -0400 Subject: [ghc-steering-committee] Proposal: Binding existential type variables (#96) In-Reply-To: <1522251757.11597.15.camel@joachim-breitner.de> References: <1522074718.24566.7.camel@joachim-breitner.de> <1522088561.24566.36.camel@joachim-breitner.de> <90ADE520-4E5F-4BCA-B11E-2DB89898F01E@cs.brynmawr.edu> <1522089839.24566.44.camel@joachim-breitner.de> <348DA9F2-FAE1-46A5-B57C-FE36EF4B55FA@cs.brynmawr.edu> <83DE2F77-F70E-4B7E-8875-CE6BC60CE211@cs.brynmawr.edu> <1522128291.1067.81.camel@joachim-breitner.de> <1522251757.11597.15.camel@joachim-breitner.de> Message-ID: - I, too, like Joachim's proposal. - I like Joachim's original proposal more than Simon's simplification... but Simon's simplification is indeed a simplification, which is nice. - If we think that we might want to migrate to Joachim's proposal eventually (and I do), then I agree with his amendment to forbid shadowing. - Joachim parenthetically mentioned the possibility of "matchable implicit arguments". We actually already have these -- they're called existential variables. What would be new is matchable /relevant/ implicit arguments, which could be matched against a pattern. Being able to match against these essentially requires Joachim's expanded proposal. - Roman asks about `data T a = MkT`, where `a`'s kind is unrestricted. This means we have `MkT :: forall {k} (a :: k). T a`. Following the current rules for specified-vs-inferred variables, the k variable is *inferred*, meaning it is not available for type application or patterns. That doesn't change here; a user of `MkT` cannot access the `k` variable through @-signs in either context. This is unchanged by #103. On balance, I favor Joachim's full proposal, without the simplification, but I favor Simon's simplification over the original proposal. Emma (the proposer), Stephanie, and I debated these designs at some length before asking Emma to write up the proposal. We did have a design with universals and existentials both able to be written explicitly in patterns, but we felt that having universals able to be types while existentials must be variables was awkward. Both new proposals on the floor treat universals and existentials similarly here, which is an improvement on anything that Emma, Stephanie, and I debated. Richard > On Mar 28, 2018, at 11:42 AM, Joachim Breitner wrote: > > Hi, > > > Am Mittwoch, den 28.03.2018, 16:37 +0100 schrieb Roman Leshchinskiy: >> On Tue, Mar 27, 2018 at 6:24 AM, Joachim Breitner wrote: >>> 2. The distinction between existentials and universals is oddly abrupt. >> >> This is a good point. In addition to what Joachim said, universals >> can also depend on existentials which I find weird. >> >> As an aside, here is one corner case which I don't think is handled >> in the proposal: >> >> data T a where >> MkT :: forall a. T a >> >> With -XPolyKinds, the type inferred for T is forall k (a :: k). T a. >> Now, k is an existential but can it be bound in a pattern? The >> proposal only mentions 2 cases: no forall and a forall that mentions >> all type variables and neither applies here. > > good point – the future of this should be addressed by > https://github.com/ghc-proposals/ghc-proposals/pull/103 > but it would be clear to be explicit in how this will be handled in #96 > until #103 is fully in place. > > 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 rae at cs.brynmawr.edu Wed Mar 28 17:10:06 2018 From: rae at cs.brynmawr.edu (Richard Eisenberg) Date: Wed, 28 Mar 2018 13:10:06 -0400 Subject: [ghc-steering-committee] DH quantifiers (#102), Recommendation: accept In-Reply-To: References: <1519400339.28221.25.camel@joachim-breitner.de> <32A4865D-5D1A-4B90-9FD3-7BB1356E0626@cs.brynmawr.edu> Message-ID: <4C756BA3-D25A-4387-99D4-DEBDA7D5FB32@cs.brynmawr.edu> Agreed with all points Simon makes below -- including on punting on #102 with a personal hope to return some day not too distant from now. I'll update the proposal with my analysis from the email. Richard > On Mar 27, 2018, at 6:11 PM, Simon Peyton Jones wrote: > > I'm on a train, and don't have access to the proposals, but here's are some thoughts: > > * #54 is about letting users write kind signatures for type constructors, > just as they can write type signatures for term variables. It's > amazing we have lasted so long without this ability, but it's really > really hurting us. I feel strongly that we should fix this: we need > SOME way to write a kind signature for a type constructor. > > * To write such a kind signature we need something like the > T :: forall a b -> blah syntax, to indicate which of T's > arguments should be written positionally (like the Int in Proxy Int) > and which are hidden (like the * in Proxy Int). By hook or by > crook we must be able to express this. And that's #81. > > * The worry with #81 was whether it would be painting us into a > corner. Hence #102. But I regard #102 as an existence proof that > the corner has an exit, not as something we should espouse now. > (Tell me if you disagree Richard.) It is far off our radar, and > premature to make a commitment. > > Richard: you could add the analysis in your email about "why 12" > to the proposal. > > So I suggest that we accept #54 and #81, and simply punt on #102. > > Simon > > | -----Original Message----- > | From: ghc-steering-committee | bounces at haskell.org> On Behalf Of Richard Eisenberg > | Sent: 27 March 2018 04:36 > | To: Iavor Diatchki > | Cc: ghc-steering-committee at haskell.org; Joachim Breitner | breitner.de> > | Subject: Re: [ghc-steering-committee] DH quantifiers (#102), > | Recommendation: accept > | > | I'd like to restart this thread, both as the Grand Poobah of Dependent > | Haskell and because Proposal #102 (this one) is holding up #81 (the > | `forall x y z ->` syntax), which is, in turn, holding up #54 (a plan to > | eliminate the need for CUSKs), which is implicated in quite a few bugs. > | > | I think Iavor makes some good criticisms below, which I'll address > | individually: > | > | > On Feb 23, 2018, at 12:12 PM, Iavor Diatchki > | wrote: > | > > | > * it is premature to "reserve" syntax for a future extension > | > | This is a hard one. The full implementation of dependent types in > | Haskell is still years away. But decisions we make now may affect the > | eventual concrete syntax. While a ghc-proposal is ill-fitted with > | reserving syntax, I think Roman was right to request that #81 be > | considered in the context of the larger syntactic changes. Maybe the > | "right" answer here is for the committee to conclude that the proposed > | syntax is generally plausible, paving the way for #81 but without making > | a solid commitment. On the other hand, if we can identify a better > | syntax for the overall design of dependent types in Haskell, that might > | affect the syntax used in #81/#54. > | > | > * I am not convinced that a design with 12 quantifiers is what I'd > | want to use > | > | Neither am I! > | > | For a moment, let's take the desire for dependent types to be a given. > | (I'll address this more below.) GHC currently has 3 quantifiers (`forall > | a.`, `ty ->`, and `ty =>`). To preserve type erasure, we need to > | distinguish between arguments needed at runtime and those that can be > | erased. > | > | Coq does this through its Set-vs-Prop mechanism, where erased arguments > | live in their own sort. Such a route is viable for Haskell, I think, but > | I've never been much enamored of it, personally. For example, the Nat in > | a vector type really can be erased, while Nats in many other places > | can't be, and it seems a shame to need two different Nat types to pull > | off this dichotomy. > | > | Agda uses the term "irrelevant" to describe type indices that are > | ignored during type equality checks. This is related to the type erasure > | property, but it's not quite the same thing. It's unclear to me what > | types Agda can erase, and I don't think Agda gives any solid guarantees > | as to erasure. (As a language aiming for performance, Haskell needs to > | provide such a guarantee.) > | > | Idris does whole-program analysis to determine erasability. I can't > | imagine this scales well. > | > | The choice I've made in the design of Dependent Haskell is to have the > | user choose whether to keep an argument or not, leading to the > | forall/foreach distinction. This brings us from 3 quantifiers to 4. In > | truth, 4 is enough to power dependent types! But read on. > | > | All dependently typed languages give a facility for the user to control > | the visibility of arguments. If we want to do the same, we go from 4 > | quantifiers to 6. (We don't go to 8 because the original -> and => > | already differ in visibility.) Note, though, that Coq doesn't consider > | visibility as a feature of a type, instead using, essentially, pragmas > | to control visibility. This has some benefits (higher-order usages of > | functions can't fall over based on visibility), but it doesn't seem > | well-suited for Haskell. > | > | Quite separately, we also will likely want to allow currying in type- > | level operations. Partially-applied type families are currently > | forbidden because doing so would wreak havoc with type inference. > | (Imagine if we're unifying `m a` with `Maybe Int` but that `m` might > | unify with a type family `Id`!) The solution I've proposed here is a > | notion of *matchability*, described in Section 4.2.4 of my thesis (which > | can be read independently of the rest of it). A function is *matchable* > | iff it is generative and injective -- in other words, if equalities over > | function applications can be decomposed. When some functions (like Maybe > | and Either Int) are matchable and some (like Id and any other type > | family) are not, then type inference can decompose matchable things and > | not decompose unmatchable things. It turns out that all previous 6 > | quantifiers are useful in both the matchable and unmatchable varieties, > | bringing us to 12. > | > | Note that other dependently typed languages don't have a notion of > | matchability. They generally also don't have injective type constructors > | (you can't derive (a ~ b) from (Maybe a ~ Maybe b)) and don't have the > | guess-free type inference Haskell has. Instead, those languages > | generally rely on higher-order unification, which is a best-guess > | algorithm (as I understand it). GHC has stayed away from guessing. We > | might imagine a future for GHC that allows partially-applied type > | functions without using matchability, but I conjecture that any such > | future would also have to offer weaker guarantees for the predictability > | and stability of type inference. It might be a fruitful debate to see > | which is better -- stable type inference or fewer quantifiers. > | > | My bottom line: I don't like the 12 quantifiers either. And dependent > | types require really only 1 new one. Two more come along for the > | convenience of invisible arguments. And then we have to double for > | matchability. (Note that matchability can be considered quite > | orthogonally to dependent types -- it has even been proposed separately > | in #52.) Perhaps I've overshot in the design here and some healthy > | debate here can whittle the number down. > | > | > * I am not convinced about the utility of the "dependent haskell" > | extension in the first place. > | > | This is the bigger question. Chapter 3 of my thesis lays out some > | motivation for dependent types, as does Chapter 8 of Adam Gundry's. > | Historically, every feature (fundeps, type families, GADTs, kind > | polymorphism, higher-rank types, type applications) that has moved GHC > | closer to having dependent types has been eagerly adopted. I've heard > | some push-back over the years about this, but the biggest complaint I've > | gotten is around termination: people don't want GHC to reject non- > | terminating functions. When I explain that doing so has never been part > | of the plan, then generally the objection is retracted. > | > | What are the downsides of adding dependent types? > | > | - The language becomes more complicated. Haskell already has a > | reputation of being impossible to learn, and if dependent types appear > | everywhere, this reputation will be reinforced, to the language's > | detriment. I am indeed worried about this. Care will have to be taken by > | library authors to make dependent types an opt-in experience. > | > | - Error messages might worsen. I'm actually not terribly worried about > | this, as I believe clever engineering can avoid it. Other than #11198 > | (which is now fixed), there has not been a degradation in error messages > | from -XTypeInType. Errors still use the words "kind" and "type" to mean > | different things! Even forgetting about dependent types, I think GHC's > | error messages need an overhaul, basically to become more like Idris's. > | (That is, interactive.) Especially if we have interactivity in error > | messages, then there are even more ways to mitigate the potential > | trouble of dependent types. Note that Haskell's tradition of language > | extensions help us here: if a user makes a type error in simple code -- > | but that code might have a meaning in a dependently typed setting -- > | then we can use the presence or absence of language extensions to tailor > | the message. (In particular, we might want to be conservative in > | recommending that the user enable -XDependentTypes.) > | > | - The abstraction will sometimes leak. The most glaring example of this > | is when the type of ($) started muttering about levity polymorphism. > | That was terrible! I do think that, with care, we can avoid this, by > | continuing to use compiler flags to tailor output and/or adding > | interactivity to GHC's output. > | > | - The implementation becomes more complicated. Well, yes, though perhaps > | we'll lose some duplication once GHC no longer has separate Expr and > | Type types. > | > | ----------------------------------------- > | > | What to do next? If others on the committee are worried about the > | desire/utility of dependent types, it might be good to seek input from > | the community. Beyond that, I'll reiterate 4 possible actions we might > | take on #102, specifically: > | > | 1. Reject the syntax. If we do this, I'd love to open a larger > | conversation of ways forward -- do we want tweaks to the syntax or a > | wholly new approach? > | > | 2. Put this idea on hold, with a plan to accept or reject #81 on its own > | merits. > | > | 3. Accept the proposal, but put implementation on the back burner. This > | would serve to reserve the syntax, without burdening our users until the > | features are more fully-formed. > | > | 4. Accept the proposal and plan to implement. > | > | Looking forward to seeing your thoughts on this, > | Richard > | _______________________________________________ > | ghc-steering-committee mailing list > | ghc-steering-committee at haskell.org > | https://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-steering-committee From simonpj at microsoft.com Thu Mar 29 18:13:27 2018 From: simonpj at microsoft.com (Simon Peyton Jones) Date: Thu, 29 Mar 2018 18:13:27 +0000 Subject: [ghc-steering-committee] Proposal: Binding existential type variables (#96) In-Reply-To: <1522250789.11597.11.camel@joachim-breitner.de> References: <1522074718.24566.7.camel@joachim-breitner.de> <1522088561.24566.36.camel@joachim-breitner.de> <90ADE520-4E5F-4BCA-B11E-2DB89898F01E@cs.brynmawr.edu> <1522089839.24566.44.camel@joachim-breitner.de> <348DA9F2-FAE1-46A5-B57C-FE36EF4B55FA@cs.brynmawr.edu> <83DE2F77-F70E-4B7E-8875-CE6BC60CE211@cs.brynmawr.edu> <1522128291.1067.81.camel@joachim-breitner.de> <1522250789.11597.11.camel@joachim-breitner.de> Message-ID: | great! I like it: It is no less expressive than the original proposal, | but forward-compatible to the full version of my proposal (which allows | types, not just type variables). I'm *much* less keen on the "full version". But I could get behind this more modest version. Would someone like to communicate something clear back to the author(s). Simon | -----Original Message----- | From: ghc-steering-committee On Behalf Of Joachim Breitner | Sent: 28 March 2018 16:26 | To: ghc-steering-committee at haskell.org | Subject: Re: [ghc-steering-committee] Proposal: Binding existential type | variables (#96) | | Hi, | | | Am Dienstag, den 27.03.2018, 21:53 +0000 schrieb Simon Peyton Jones: | > Interesting idea from Joachim. But it's quite complicated. | > Here is a much simpler version. | | great! I like it: It is no less expressive than the original proposal, | but forward-compatible to the full version of my proposal (which allows | types, not just type variables). I believe we will want the full | version eventually (Both to say `foo (Nothing @Int) = …` and once we | have matchable implicit argument – right, Richard?), but we don’t have | to do both steps at once. | | May I add one constraint to the simpler alternative proposal: | | It is an error to @-bind a type variables that would shadow | type variable that is already in scope (whether from | ScopedTypeVariables, from an instance head or from a @-binder). | | | Why? Well, for forward compatibility. But also for consistency! To our | users (or, at least to me) these two expressions are different ways of | writing the same things: | | foo1, foo1' :: forall a. a -> Int | foo1 x = length (Nothing :: Maybe a) | foo1' x = length (Nothing @ a) | | I.e. TypeApplication is just a more convenient alternative to type | signatures. | | The same is true, in patterns, under your simplified alternative | proposal: | | foo2, foo2' :: a -> Maybe Int -> Int | foo2 _ (Nothing :: Maybe a) = 42 | foo2' _ (Nothing @ a) = 42 | | In both forms, a is bound by the pattern (and `a ~ Int` is added to the | context). | | But note that a change somewhere else (and it could be arbitrarily far | away if `foo2` is a local function) breaks the symmetry, at least with | ScopedTypeVariables enabled: | | foo3, foo3' :: forall a. a -> Maybe Int -> Int | foo3 _ (Nothing :: Maybe a) = 42 -- type error (a ≠ Int) | foo3' _ (Nothing @ a) = 42 -- shadows a | | Hence I would ask to simply forbid the latter form in the simplified | version of the proposal. This | * helps the user not shooting in his own leg and | * is compatible with the full proposal, where | foo3 and foo3' would be equivalent. | | | Cheers, | Joachim | -- | Joachim Breitner | mail at joachim-breitner.de | | https://na01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fwww.joac | him- | breitner.de%2F&data=02%7C01%7Csimonpj%40microsoft.com%7Cf159ca2e41fd41ca | b59d08d594c04f60%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C6365784760 | 41656384&sdata=FepuCZE2%2FlQMlBssUMTyHEBmFoyjAVXY%2FXJrsdUxd6Q%3D&reserv | ed=0