Conditional compilation for different versions of GHC?

Dear list,
From ghc 7.0.1 release notes:
The Language.Haskell.TH.Quote.QuasiQuoter type has two new fields: quoteType and quoteDec.
Some of my code needs to be conditionally compiled to support both version 6 and 7, what is the recommended way to do it? ref: * http://new-www.haskell.org/ghc/docs/7.0.1/html/users_guide/release-7-0-1.htm... -- jinjing

On Sat, Nov 27, 2010 at 6:59 PM, Jinjing Wang
Dear list,
From ghc 7.0.1 release notes:
The Language.Haskell.TH.Quote.QuasiQuoter type has two new fields: quoteType and quoteDec.
Some of my code needs to be conditionally compiled to support both version 6 and 7, what is the recommended way to do it?
ref:
* http://new-www.haskell.org/ghc/docs/7.0.1/html/users_guide/release-7-0-1.htm...
Hi Jinjing, I've done this in Yesod. I'm not sure if it's the best way, but basically I've added a ghc7 flag to the cabal file, and a block for the library that reads: if flag(ghc7) build-depends: base >= 4.3 && < 5 cpp-options: -DGHC7 else build-depends: base >= 4 && < 4.3 Then whenever I want to quasi-quote in the code, I write: #if GHC7 [quasiquoter| #else [$quasiquoter| #endif Michael

Thanks Michael,
So the user should use `cabal install --flags -ghc7 package-name` to
install the package, if I'm not mistaken?
Will it work if the package is installed as a dependency? Will the
flag environment be passed down from the root package?
Is there a way to detect GHC version automatically?
: )
Best,
On Sun, Nov 28, 2010 at 1:32 AM, Michael Snoyman
On Sat, Nov 27, 2010 at 6:59 PM, Jinjing Wang
wrote: Dear list,
From ghc 7.0.1 release notes:
The Language.Haskell.TH.Quote.QuasiQuoter type has two new fields: quoteType and quoteDec.
Some of my code needs to be conditionally compiled to support both version 6 and 7, what is the recommended way to do it?
ref:
* http://new-www.haskell.org/ghc/docs/7.0.1/html/users_guide/release-7-0-1.htm...
Hi Jinjing,
I've done this in Yesod. I'm not sure if it's the best way, but basically I've added a ghc7 flag to the cabal file, and a block for the library that reads:
if flag(ghc7) build-depends: base >= 4.3 && < 5 cpp-options: -DGHC7 else build-depends: base >= 4 && < 4.3
Then whenever I want to quasi-quote in the code, I write:
#if GHC7 [quasiquoter| #else [$quasiquoter| #endif
Michael
-- jinjing

Sorry, should be `cabal install --flags="ghc7" package-name`.
On Sun, Nov 28, 2010 at 1:59 AM, Jinjing Wang
Thanks Michael,
So the user should use `cabal install --flags -ghc7 package-name` to install the package, if I'm not mistaken?
Will it work if the package is installed as a dependency? Will the flag environment be passed down from the root package?
Is there a way to detect GHC version automatically?
: )
Best,
On Sun, Nov 28, 2010 at 1:32 AM, Michael Snoyman
wrote: On Sat, Nov 27, 2010 at 6:59 PM, Jinjing Wang
wrote: Dear list,
From ghc 7.0.1 release notes:
The Language.Haskell.TH.Quote.QuasiQuoter type has two new fields: quoteType and quoteDec.
Some of my code needs to be conditionally compiled to support both version 6 and 7, what is the recommended way to do it?
ref:
* http://new-www.haskell.org/ghc/docs/7.0.1/html/users_guide/release-7-0-1.htm...
Hi Jinjing,
I've done this in Yesod. I'm not sure if it's the best way, but basically I've added a ghc7 flag to the cabal file, and a block for the library that reads:
if flag(ghc7) build-depends: base >= 4.3 && < 5 cpp-options: -DGHC7 else build-depends: base >= 4 && < 4.3
Then whenever I want to quasi-quote in the code, I write:
#if GHC7 [quasiquoter| #else [$quasiquoter| #endif
Michael
-- jinjing
-- jinjing

No, the user doesn't need to do anything. By splitting up the "base"
range into pre-7 and post-7, cabal automatically applies the ghc7 flag
(and thus adds the GHC7 CPP declaration) as appropriate.
Michael
On Sat, Nov 27, 2010 at 7:59 PM, Jinjing Wang
Thanks Michael,
So the user should use `cabal install --flags -ghc7 package-name` to install the package, if I'm not mistaken?
Will it work if the package is installed as a dependency? Will the flag environment be passed down from the root package?
Is there a way to detect GHC version automatically?
: )
Best,
On Sun, Nov 28, 2010 at 1:32 AM, Michael Snoyman
wrote: On Sat, Nov 27, 2010 at 6:59 PM, Jinjing Wang
wrote: Dear list,
From ghc 7.0.1 release notes:
The Language.Haskell.TH.Quote.QuasiQuoter type has two new fields: quoteType and quoteDec.
Some of my code needs to be conditionally compiled to support both version 6 and 7, what is the recommended way to do it?
ref:
* http://new-www.haskell.org/ghc/docs/7.0.1/html/users_guide/release-7-0-1.htm...
Hi Jinjing,
I've done this in Yesod. I'm not sure if it's the best way, but basically I've added a ghc7 flag to the cabal file, and a block for the library that reads:
if flag(ghc7) build-depends: base >= 4.3 && < 5 cpp-options: -DGHC7 else build-depends: base >= 4 && < 4.3
Then whenever I want to quasi-quote in the code, I write:
#if GHC7 [quasiquoter| #else [$quasiquoter| #endif
Michael
-- jinjing

On Sat, Nov 27, 2010 at 9:59 AM, Jinjing Wang
Thanks Michael,
So the user should use `cabal install --flags -ghc7 package-name` to install the package, if I'm not mistaken?
Will it work if the package is installed as a dependency? Will the flag environment be passed down from the root package?
Is there a way to detect GHC version automatically?
I see that others have provided answers on here, but another way is to change the check from: if flag(ghc7) build-depends: base >= 4.3 && < 5 cpp-options: -DGHC7 else build-depends: base >= 4 && < 4.3 to this: if impl(ghc >= 7) build-depends: base >= 4.3 && < 5 cpp-options: -DGHC7 else build-depends: base >= 4 && < 4.3 I hope that helps, Jason

Jason Dagit schrieb:
I see that others have provided answers on here, but another way is to change the check from:
if flag(ghc7) build-depends: base >= 4.3 && < 5 cpp-options: -DGHC7 else build-depends: base >= 4 && < 4.3
to this: if impl(ghc >= 7) build-depends: base >= 4.3 && < 5 cpp-options: -DGHC7 else build-depends: base >= 4 && < 4.3
Isn't it better to move the dependency on 'base' out of the If block? I mean, someone might succeed to use GHC-7 with base-4.2 or GHC<7 or a different compiler with base-4.3.

-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 On 12/5/10 17:05 , Henning Thielemann wrote:
Isn't it better to move the dependency on 'base' out of the If block? I mean, someone might succeed to use GHC-7 with base-4.2 or GHC<7 or a different compiler with base-4.3.
Since the base package is (with good reason) part of the compiler, anyone smart enough to get that to work is smart enough to edit the cabal file. - -- brandon s. allbery [linux,solaris,freebsd,perl] allbery@kf8nh.com system administrator [openafs,heimdal,too many hats] allbery@ece.cmu.edu electrical and computer engineering, carnegie mellon university KF8NH -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.10 (Darwin) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/ iEYEARECAAYFAkz8GukACgkQIn7hlCsL25WTxACfc4k/3GoQr402TbVFmabRD7sJ 7WEAoMnmLeaKGfjQdjdP4K60Ch6g72md =LZuU -----END PGP SIGNATURE-----

On Sat, Nov 27, 2010 at 10:59 AM, Jinjing Wang
Dear list,
From ghc 7.0.1 release notes:
The Language.Haskell.TH.Quote.QuasiQuoter type has two new fields: quoteType and quoteDec.
Some of my code needs to be conditionally compiled to support both version 6 and 7, what is the recommended way to do it?
ref:
* http://new-www.haskell.org/ghc/docs/7.0.1/html/users_guide/release-7-0-1.htm...
Can you just not set those fields? Then the code should work as-is for both versions. You'll get warnings for GHC 7, I think. Antoine

On Sat, Nov 27, 2010 at 9:41 PM, Antoine Latter
On Sat, Nov 27, 2010 at 10:59 AM, Jinjing Wang
wrote: Dear list,
From ghc 7.0.1 release notes:
The Language.Haskell.TH.Quote.QuasiQuoter type has two new fields: quoteType and quoteDec.
Some of my code needs to be conditionally compiled to support both version 6 and 7, what is the recommended way to do it?
ref:
* http://new-www.haskell.org/ghc/docs/7.0.1/html/users_guide/release-7-0-1.htm...
Can you just not set those fields? Then the code should work as-is for both versions. You'll get warnings for GHC 7, I think.
Sorry Jinjing, I didn't read your original email carefully enough. Antoine is absolutely correct, this is the better way to deal with defining a quasiquoter. My suggestion is only necessary if you want to *use* a quasiquoter. Michael

Hi Michael, you are absolutely correct, cabal did set the flags automatically.
To sum up, here's what needs to be done:
* add `flag ghc7` as a field in cabal
* add:
if flag(ghc7)
build-depends: base >= 4.3 && < 5
cpp-options: -DGHC7
else
build-depends: base >= 4 && < 4.3
in library field in cabal
* add `{-# LANGUAGE CPP #-}` in source file
* add
#if GHC7
x
#else
y
#endif
Hi Antonine, I don't know how to not set those fields in the
constructor.. as a QQ noob, I'm just hacking on some legacy code. This
code doesn't compile in GHC7, so I have to do this trick.
* https://github.com/nfjinjing/mps/blob/master/src/MPS/TH.hs
Best,
On Sun, Nov 28, 2010 at 3:48 AM, Michael Snoyman
On Sat, Nov 27, 2010 at 9:41 PM, Antoine Latter
wrote: On Sat, Nov 27, 2010 at 10:59 AM, Jinjing Wang
wrote: Dear list,
From ghc 7.0.1 release notes:
The Language.Haskell.TH.Quote.QuasiQuoter type has two new fields: quoteType and quoteDec.
Some of my code needs to be conditionally compiled to support both version 6 and 7, what is the recommended way to do it?
ref:
* http://new-www.haskell.org/ghc/docs/7.0.1/html/users_guide/release-7-0-1.htm...
Can you just not set those fields? Then the code should work as-is for both versions. You'll get warnings for GHC 7, I think.
Sorry Jinjing, I didn't read your original email carefully enough. Antoine is absolutely correct, this is the better way to deal with defining a quasiquoter. My suggestion is only necessary if you want to *use* a quasiquoter.
Michael
-- jinjing

On Sat, Nov 27, 2010 at 8:38 PM, Jinjing Wang
Hi Michael, you are absolutely correct, cabal did set the flags automatically.
To sum up, here's what needs to be done:
* add `flag ghc7` as a field in cabal * add:
if flag(ghc7) build-depends: base >= 4.3 && < 5 cpp-options: -DGHC7 else build-depends: base >= 4 && < 4.3
in library field in cabal
* add `{-# LANGUAGE CPP #-}` in source file * add
#if GHC7 x
#else y
#endif
Hi Antonine, I don't know how to not set those fields in the constructor.. as a QQ noob, I'm just hacking on some legacy code. This code doesn't compile in GHC7, so I have to do this trick.
* https://github.com/nfjinjing/mps/blob/master/src/MPS/TH.hs
Something like: myQuoter = QuasiQuoter { quoteExp = expQuoter, quotePat = patQuoter } Will work in either version, but it will leave the un-set fields set to `undefined`, so you'll get a compile error if you try to use them. I haven't tested this, but I've done it with other record types. Take care, Antoine

Thanks for explaining, it's a nice trick.
On Sun, Nov 28, 2010 at 11:16 AM, Antoine Latter
On Sat, Nov 27, 2010 at 8:38 PM, Jinjing Wang
wrote: Hi Michael, you are absolutely correct, cabal did set the flags automatically.
To sum up, here's what needs to be done:
* add `flag ghc7` as a field in cabal * add:
if flag(ghc7) build-depends: base >= 4.3 && < 5 cpp-options: -DGHC7 else build-depends: base >= 4 && < 4.3
in library field in cabal
* add `{-# LANGUAGE CPP #-}` in source file * add
#if GHC7 x
#else y
#endif
Hi Antonine, I don't know how to not set those fields in the constructor.. as a QQ noob, I'm just hacking on some legacy code. This code doesn't compile in GHC7, so I have to do this trick.
* https://github.com/nfjinjing/mps/blob/master/src/MPS/TH.hs
Something like:
myQuoter = QuasiQuoter { quoteExp = expQuoter, quotePat = patQuoter }
Will work in either version, but it will leave the un-set fields set to `undefined`, so you'll get a compile error if you try to use them.
I haven't tested this, but I've done it with other record types.
Take care, Antoine
-- jinjing

Hi Antoine, Thanks for pointing out, it did work.
By using a record style constructor, the code can be made to support
both version, something like
here = QuasiQuoter
{
quoteExp = (litE . stringL)
, quotePat = (litP . stringL)
}
in GHC7 there's a warning:
Warning: Fields of `QuasiQuoter' not initialised: quoteType, quoteDec
So far it works without problem.
On Sun, Nov 28, 2010 at 10:38 AM, Jinjing Wang
Hi Michael, you are absolutely correct, cabal did set the flags automatically.
To sum up, here's what needs to be done:
* add `flag ghc7` as a field in cabal * add:
if flag(ghc7) build-depends: base >= 4.3 && < 5 cpp-options: -DGHC7 else build-depends: base >= 4 && < 4.3
in library field in cabal
* add `{-# LANGUAGE CPP #-}` in source file * add
#if GHC7 x
#else y
#endif
Hi Antonine, I don't know how to not set those fields in the constructor.. as a QQ noob, I'm just hacking on some legacy code. This code doesn't compile in GHC7, so I have to do this trick.
* https://github.com/nfjinjing/mps/blob/master/src/MPS/TH.hs
Best,
On Sun, Nov 28, 2010 at 3:48 AM, Michael Snoyman
wrote: On Sat, Nov 27, 2010 at 9:41 PM, Antoine Latter
wrote: On Sat, Nov 27, 2010 at 10:59 AM, Jinjing Wang
wrote: Dear list,
From ghc 7.0.1 release notes:
The Language.Haskell.TH.Quote.QuasiQuoter type has two new fields: quoteType and quoteDec.
Some of my code needs to be conditionally compiled to support both version 6 and 7, what is the recommended way to do it?
ref:
* http://new-www.haskell.org/ghc/docs/7.0.1/html/users_guide/release-7-0-1.htm...
Can you just not set those fields? Then the code should work as-is for both versions. You'll get warnings for GHC 7, I think.
Sorry Jinjing, I didn't read your original email carefully enough. Antoine is absolutely correct, this is the better way to deal with defining a quasiquoter. My suggestion is only necessary if you want to *use* a quasiquoter.
Michael
-- jinjing
-- jinjing

I think a nicer way to solve that issue is to use Cabal's MIN_VERSION macros.
1. Add CPP to your extensions. This will cause cabal to
auto-generate a file with MIN_VERSION_<pkg> macros for each <pkg> in
build-depends.
2. GHC 6.12.* comes with template-haskell 2.4, so to test for that use:
#ifdef MIN_VERSION_template_haskell(2,4,0)
.. ghc-6.12.* code here.
#endif
This should make it more transparent to the user.
On 27 November 2010 16:59, Jinjing Wang
Dear list,
From ghc 7.0.1 release notes:
The Language.Haskell.TH.Quote.QuasiQuoter type has two new fields: quoteType and quoteDec.
Some of my code needs to be conditionally compiled to support both version 6 and 7, what is the recommended way to do it?
ref:
* http://new-www.haskell.org/ghc/docs/7.0.1/html/users_guide/release-7-0-1.htm...
-- jinjing _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
-- Push the envelope. Watch it bend.

On Wed, Dec 1, 2010 at 4:07 AM, Thomas Schilling
I think a nicer way to solve that issue is to use Cabal's MIN_VERSION macros.
1. Add CPP to your extensions. This will cause cabal to auto-generate a file with MIN_VERSION_<pkg> macros for each <pkg> in build-depends.
2. GHC 6.12.* comes with template-haskell 2.4, so to test for that use:
#ifdef MIN_VERSION_template_haskell(2,4,0) .. ghc-6.12.* code here. #endif
This should make it more transparent to the user.
This is obviously a personal preference issue, but I try to avoid the Cabal macros since they don't let my code run outside the context of Cabal. I often times like to have a test suite that I can just use with runhaskell, and (unless you can tell me otherwise) I can't run it anymore. Also, I think #if GHC7 ... #endif is more transparent than a check on template-haskell. Michael

This is obviously a personal preference issue, but I try to avoid the Cabal macros since they don't let my code run outside the context of Cabal. I often times like to have a test suite that I can just use with runhaskell, and (unless you can tell me otherwise) I can't run it anymore.
Also, I think
#if GHC7 ... #endif
is more transparent than a check on template-haskell.
Just in case this hasn't been mentioned yet: if you want to be independent of cabal, there is the old standby __GLASGOW_HASKELL__ http://haskell.org/ghc/docs/latest/html/users_guide/options-phases.html#c-pr... Claus

On Wed, Dec 1, 2010 at 6:58 PM, Claus Reinke
This is obviously a personal preference issue, but I try to avoid the Cabal macros since they don't let my code run outside the context of Cabal. I often times like to have a test suite that I can just use with runhaskell, and (unless you can tell me otherwise) I can't run it anymore.
Also, I think
#if GHC7 ... #endif
is more transparent than a check on template-haskell.
Just in case this hasn't been mentioned yet: if you want to be independent of cabal, there is the old standby
__GLASGOW_HASKELL__ http://haskell.org/ghc/docs/latest/html/users_guide/options-phases.html#c-pr...
Well, I think this is the official right approach. I was not aware of that, thank you Claus. Michael

On 1 December 2010 03:54, Michael Snoyman
On Wed, Dec 1, 2010 at 4:07 AM, Thomas Schilling
wrote: I think a nicer way to solve that issue is to use Cabal's MIN_VERSION macros.
1. Add CPP to your extensions. This will cause cabal to auto-generate a file with MIN_VERSION_<pkg> macros for each <pkg> in build-depends.
2. GHC 6.12.* comes with template-haskell 2.4, so to test for that use:
#ifdef MIN_VERSION_template_haskell(2,4,0) .. ghc-6.12.* code here. #endif
This should make it more transparent to the user.
Also, I think
#if GHC7 ... #endif
is more transparent than a check on template-haskell.
Note that in many cases it is inappropriate to use the ghc version as a proxy for a library version since most libraries are upgradable independently of GHC. Duncan
participants (9)
-
Antoine Latter
-
Brandon S Allbery KF8NH
-
Claus Reinke
-
Duncan Coutts
-
Henning Thielemann
-
Jason Dagit
-
Jinjing Wang
-
Michael Snoyman
-
Thomas Schilling