Hi all, Currently we do not have GADT support in Template Haskell, but I need it for something I'm working on. The relevant datastructures currently look like this: data Dec = ... | DataD Cxt Name [Name] [Con] [Name] | ... data Con = NormalC Name [StrictType] | RecC Name [VarStrictType] | InfixC StrictType Name StrictType | ForallC [Name] Cxt Con I propose altering Dec thus: data Dec = ... | DataD Cxt Name [Name] Cons [Name] | ... (changing [Con] to Cons) and adding new datastructures: data Cons = NormalCons [Con] | GadtCons [GadtCon] deriving( Show, Eq ) data GadtCon = GadtC [Name] Cxt Name [StrictType] Type deriving( Show, Eq ) (this follows the style used to add pattern guards to the datastructures). Complete patches for GHC and the template-haskell library are at http://urchin.earth.li/~ian/th-gadts/ If you have any objections or comments then please let me know; otherwise I think it would be great to get this into GHC 6.6. Thanks Ian
On 11.08 23:25, Ian Lynagh wrote:
If you have any objections or comments then please let me know; otherwise I think it would be great to get this into GHC 6.6.
Why not simple represent all data declarations as GADT to the user? Generally TH code should not care between: data Foo = Foo Int and data Foo where Foo :: Int -> Foo data B = forall Show x. B x and data B where B :: Show a => a -> B But any way to support GADTs would be better than the current situation. - Einar Karttunen
On Sat, Aug 12, 2006 at 10:26:06AM +0300, Einar Karttunen wrote:
On 11.08 23:25, Ian Lynagh wrote:
If you have any objections or comments then please let me know; otherwise I think it would be great to get this into GHC 6.6.
Why not simple represent all data declarations as GADT to the user?
Because GADTs cannot represent record constructors. I didn't make GadtC a constructor for Con as I don't think you could pretty-print a datatype with both GADT and record constructors. Also, TH tries to present the completely sugared language to the user; otherwise it would probably work on something more like core. Thanks Ian
On 12.08 10:26, Ian Lynagh wrote:
On Sat, Aug 12, 2006 at 10:26:06AM +0300, Einar Karttunen wrote:
On 11.08 23:25, Ian Lynagh wrote:
If you have any objections or comments then please let me know; otherwise I think it would be great to get this into GHC 6.6.
Why not simple represent all data declarations as GADT to the user?
Because GADTs cannot represent record constructors. I didn't make GadtC a constructor for Con as I don't think you could pretty-print a datatype with both GADT and record constructors.
GHC 6.5 does support that. http://www.haskell.org/hawiki/GADT_20with_20record_20syntax
Also, TH tries to present the completely sugared language to the user; otherwise it would probably work on something more like core.
Point. Usually when using TH I *wish* it was more like core - or that there would be at least a way to simplify expressions. - Einar Karttunen
Hello Einar, Saturday, August 12, 2006, 3:50:55 PM, you wrote:
Point. Usually when using TH I *wish* it was more like core - or that there would be at least a way to simplify expressions.
it may be written as lib. you already implemented something of this kind in SerTH (and i borrowed this code :) -- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com
| Also, TH tries to present the completely sugared language to the user; | otherwise it would probably work on something more like core. This really is a tension, and one I don't really know how to resolve. GHC does represent fully-sugared syntax, including even the placement of parens. I don't think TH need go to these lengths. TH generates code that we might read, but which is mainly intended to be compiled. It's *also* intended to be processed by other TH code, so the smaller the TH data type, the better. I conclude that TH should avoid gratuitous syntactic sugar. Anything that can be converted to a simpler equivalent form, should be. Hence I rather think that infix operators in TH are a mistake. What do they really buy us? Similarly an if-expression, and arithmetic sequence, and list expressions. On the other hand, a list comprehension is much more complicated to desugar, so probably deserves to be there. It'd be good to discuss this and perhaps agree some changes. Concerning data types, I think it'd be fine to present data types in a single, canonical representation as a data type, probably something like the GADT style. That'd be a breaking change, mind you. Because there are design choices here, I'm dubious about getting any of this into 6.6. Time is very short, and we don't want to make a change that we re-change later. Simon
Hello Simon, Monday, August 14, 2006, 12:51:08 PM, you wrote:
I don't think TH need go to these lengths. TH generates code that we might read, but which is mainly intended to be compiled. It's *also* intended to be processed by other TH code, so the smaller the TH data type, the better.
i propose to place this question into more global frame - what is a TH unique place among other Haskell extensions? imho, TH is (at least) an attempt to develop macro-preprocessing feature that is able to accomplish tasks in ways not accessible to the bare language this means that TH competes with such tools as Lisp macros and C preprocessor. and imho, TH should evolve in the way that will eventually allow to include it in the Haskell standard. this means, in particular, that we should divide it into Haskell-compatible features and GHC extensions second, it will be interesting to implement TH as true preprocessing tool generating Haskell code that can be compiled by any *hc third, as you said, TH should simplify two different tasks - analyzing of existing Haskell code and generating new one. For that, we can allow to use full Haskell/GHC power in code constructed by user functions but at the same time pass to these functions already desugared code; i.e. make input data as simple as possible while allow to use in output data as much features as one want another solution will be implementing desugaring functions that accepts full-fledged Exp/Dec/... and returns desugared one. this solution don't need any changes in existing code and can be implemented without any changes to core TH implementation, it's just additional user-level functions
I conclude that TH should avoid gratuitous syntactic sugar. Anything that can be converted to a simpler equivalent form, should be. Hence I rather think that infix operators in TH are a mistake. What do they really buy us? Similarly an if-expression, and arithmetic sequence, and list expressions. On the other hand, a list comprehension is much more complicated to desugar, so probably deserves to be there.
It'd be good to discuss this and perhaps agree some changes.
Concerning data types, I think it'd be fine to present data types in a single, canonical representation as a data type, probably something like the GADT style. That'd be a breaking change, mind you.
this will break almost all existing TH programs, made Dec ghc-specific and require incompatible changes that we should wait until ghc 6.8 on the other side, adding new variant to existing Dec type is obvious. one can then write desugarer that turns any type definition into GADT one so i propose to keep TH declarations a mirror of official H98 syntax, add new variants for GHC-specific extensions, and implement desugaring functions to simplify TH usage. at the last end, we can got official H2098 report where Haskell syntax defined in terms of Haskell data structures and desugarer as Haskell program :) -- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com
On 14.08 14:07, Bulat Ziganshin wrote:
this means that TH competes with such tools as Lisp macros and C preprocessor. and imho, TH should evolve in the way that will eventually allow to include it in the Haskell standard. this means, in particular, that we should divide it into Haskell-compatible features and GHC extensions
Having a generic Dec that supports GADT in the most general form possible would be good for standardization. Each implementation would only generate the subset of legal definitions in that implementation and complain if the user tried to use more generic ones. All standard data declarations can be easily expressed as a GADT. This would make code work easier in different compilers with different extensions.
third, as you said, TH should simplify two different tasks - analyzing of existing Haskell code and generating new one. For that, we can allow to use full Haskell/GHC power in code constructed by user functions but at the same time pass to these functions already desugared code; i.e. make input data as simple as possible while allow to use in output data as much features as one want
Simple datatypes + intelligent constructors.
another solution will be implementing desugaring functions that accepts full-fledged Exp/Dec/... and returns desugared one. this solution don't need any changes in existing code and can be implemented without any changes to core TH implementation, it's just additional user-level functions
This means that pattern matching will be always incomplete - which is not nice.
this will break almost all existing TH programs, made Dec ghc-specific and require incompatible changes that we should wait until ghc 6.8
Dec is already GHC-specific. I agree that 6.6 is too soon.
on the other side, adding new variant to existing Dec type is obvious. one can then write desugarer that turns any type definition into GADT one
The more variants we add the harder using TH comes. Just version the package and keep an old version installed alongside the new one. Thus old libraries will be fine.
so i propose to keep TH declarations a mirror of official H98 syntax, add new variants for GHC-specific extensions, and implement desugaring functions to simplify TH usage. at the last end, we can got official H2098 report where Haskell syntax defined in terms of Haskell data structures and desugarer as Haskell program :)
TH has never been H98. I think we should have the actual datatypes as simple as possible to make pattern matching easy. Providing intelligent constructor functions to support language constructs should be the way. - Einar Karttunen
Hello Einar, Monday, August 14, 2006, 5:28:08 PM, you wrote:
Having a generic Dec that supports GADT in the most general form possible would be good for standardization. Each implementation would only generate the subset of legal definitions in that implementation and complain if the user tried to use more generic ones.
All standard data declarations can be easily expressed as a GADT.
This would make code work easier in different compilers with different extensions.
this looks fine except that ghc-specific language facilities will be exposed to other compilers
Simple datatypes + intelligent constructors.
good alternative. i agree that this is the better. except perhaps for situations when one want to know exact syntax what was used in some Haskell code. but is anyone need this?
another solution will be implementing desugaring functions that accepts full-fledged Exp/Dec/... and returns desugared one. this solution don't need any changes in existing code and can be implemented without any changes to core TH implementation, it's just additional user-level functions
This means that pattern matching will be always incomplete - which is not nice.
yes, it's not ideal solution. but adding new features to language and mirroring them in TH datatypes also makes old code incomplete ;)
this will break almost all existing TH programs, made Dec ghc-specific and require incompatible changes that we should wait until ghc 6.8
Dec is already GHC-specific. I agree that 6.6 is too soon.
i propose to drive TH into the direction of making general Haskell utility that at some moment may become part of the official language instead of increasing this incompatibility
on the other side, adding new variant to existing Dec type is obvious. one can then write desugarer that turns any type definition into GADT one
The more variants we add the harder using TH comes. Just version the package and keep an old version installed alongside the new one. Thus old libraries will be fine.
i'm not sure that this will work with TH, which needs compiler support. Is GHC 6.8 should support generation of ASTs for all TH versions ever developed? :)
so i propose to keep TH declarations a mirror of official H98 syntax, add new variants for GHC-specific extensions, and implement desugaring functions to simplify TH usage. at the last end, we can got official H2098 report where Haskell syntax defined in terms of Haskell data structures and desugarer as Haskell program :)
TH has never been H98.
i propose to drive it into this direction. Of course, it will not become even part of H' standard, but at least making TH subset that supports current Haskell standard will be a good step toward TH standardization and making it available for other compilers
I think we should have the actual datatypes as simple as possible to make pattern matching easy. Providing intelligent constructor functions to support language constructs should be the way.
yes, that's great and, i think that adding TH constructs for all new language features in 6.6 is really important for all TH developers. otherwise, we will be like one-armed invalid. if SPJ don't want to change TH datatypes after 6.6 release, it should be done just now -- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com
| and, i think that adding TH constructs for all new language features | in 6.6 is really important for all TH developers. otherwise, we will | be like one-armed invalid. if SPJ don't want to change TH datatypes | after 6.6 release, it should be done just now Quite the reverse. I think it's dangerous to fiddle just now, because there is only a matter of days before 6.6 is fixed. But after 6.6 we can review the data types and change them if there's a consensus. The exact design isn't something about which I feel strongly, apart from the principle in my previous message (avoiding gratuitous sugar) Simon
Hello Simon, Monday, August 14, 2006, 6:43:25 PM, you wrote:
| and, i think that adding TH constructs for all new language features | in 6.6 is really important for all TH developers. otherwise, we will | be like one-armed invalid. if SPJ don't want to change TH datatypes | after 6.6 release, it should be done just now
Quite the reverse. I think it's dangerous to fiddle just now, because there is only a matter of days before 6.6 is fixed. But after 6.6 we can review the data types and change them if there's a consensus. The exact design isn't something about which I feel strongly, apart from the principle in my previous message (avoiding gratuitous sugar)
i hope that you will include this in 6.6.1 despite the fact that it backward incompatible change? otherwise, postponing using of GADTs with TH until 6.8 will be not so great.. -- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com
Patch-level releases *never* change interfaces, so we can't do this in 6.6.1. It's a pity all this has come up days before the 6.6 freeze. It's a year since 6.4 came out, so there's been plenty of time! There are always more things to put in, so one has to stop somewhere. You can argue, if you like, to delay 6.6 by a month. But we don't even know how long it would take to have the design discussion Simon | -----Original Message----- | From: Bulat Ziganshin [mailto:bulat.ziganshin@gmail.com] | Sent: 14 August 2006 16:22 | To: Simon Peyton-Jones | Cc: Bulat Ziganshin; Einar Karttunen; template-haskell@haskell.org | Subject: Re[4]: [Template-haskell] GADTs | | Hello Simon, | | Monday, August 14, 2006, 6:43:25 PM, you wrote: | | > | and, i think that adding TH constructs for all new language features | > | in 6.6 is really important for all TH developers. otherwise, we will | > | be like one-armed invalid. if SPJ don't want to change TH datatypes | > | after 6.6 release, it should be done just now | | > Quite the reverse. I think it's dangerous to fiddle just now, because | > there is only a matter of days before 6.6 is fixed. But after 6.6 we | > can review the data types and change them if there's a consensus. The | > exact design isn't something about which I feel strongly, apart from the | > principle in my previous message (avoiding gratuitous sugar) | | i hope that you will include this in 6.6.1 despite the fact that it | backward incompatible change? otherwise, postponing using of GADTs | with TH until 6.8 will be not so great.. | | | | -- | Best regards, | Bulat mailto:Bulat.Ziganshin@gmail.com
Hello Simon, Monday, August 14, 2006, 9:01:31 PM, you wrote:
Patch-level releases *never* change interfaces, so we can't do this in 6.6.1.
It's a pity all this has come up days before the 6.6 freeze. It's a year since 6.4 came out, so there's been plenty of time! There are always more things to put in, so one has to stop somewhere.
You can argue, if you like, to delay 6.6 by a month. But we don't even know how long it would take to have the design discussion
well, i never mind to stay between you and your release date. it's like staying between bullet and it's target :) -- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com
On Aug 14, 2006, at 4:51 AM, Simon Peyton-Jones wrote:
| Also, TH tries to present the completely sugared language to the user; | otherwise it would probably work on something more like core.
This really is a tension, and one I don't really know how to resolve.
GHC does represent fully-sugared syntax, including even the placement of parens.
I don't think TH need go to these lengths. TH generates code that we might read, but which is mainly intended to be compiled. It's *also* intended to be processed by other TH code, so the smaller the TH data type, the better.
I conclude that TH should avoid gratuitous syntactic sugar. Anything that can be converted to a simpler equivalent form, should be. Hence I rather think that infix operators in TH are a mistake. What do they really buy us? Similarly an if-expression, and arithmetic sequence, and list expressions. On the other hand, a list comprehension is much more complicated to desugar, so probably deserves to be there.
It'd be good to discuss this and perhaps agree some changes.
Concerning data types, I think it'd be fine to present data types in a single, canonical representation as a data type, probably something like the GADT style. That'd be a breaking change, mind you.
I'd just like to voice my agreement with this general idea. I might even suggest going one step further; divorce the world of TH from the Haskell front end altogether. Specify that TH operates in a convenient core language which is general enough to cover all the interesting haskell extensions (say, Fc http://research.microsoft.com/ %7Esimonpj/papers/ext%2Df/). Then, various implementations of TH can simply differ in the TH programs they accept (eg, a pure H98 impl might only accept the Fc fragment with sort TY). But I think the important thing is to specify TH in a way that is at least somewhat independent of other haskell extensions. Of course, the devil's in the details...
Because there are design choices here, I'm dubious about getting any of this into 6.6. Time is very short, and we don't want to make a change that we re-change later.
Simon
Rob Dockins Speak softly and drive a Sherman tank. Laugh hard; it's a long way to the bank. -- TMBG
participants (5)
-
Bulat Ziganshin -
Einar Karttunen -
Ian Lynagh -
Robert Dockins -
Simon Peyton-Jones