MIN_VERSION_foo() macro vs. CABAL-flag directed API-adaption

Hello, When I noticed the recently released HTTP-4000.2.5[1] package used a CABAL-flag based approach[2] for what I expected the use of a macro MIN_VERSION_network(2,4,0) to be more appropriate (see [3]), I wasn't totally sure whether there was any down-side with the MIN_VERSION_-approach. So my question is: Is it always desirable to prefer the MIN_VERSION_ approach over a CABAL-flag approach for supporting multiple API versions of a dependent package (if both ways are possible)? And if not, when should I prefer which approach? [1]: http://hackage.haskell.org/package/HTTP-4000.2.5 [2]: https://github.com/haskell/HTTP/commit/7a266219284ff33d66fa5e3f67f406c2616fe... [3]: https://github.com/haskell/HTTP/pull/30 cheers, hvr --

On Tue, Sep 18, 2012 at 12:41:50PM +0200, Herbert Valerio Riedel wrote:
Is it always desirable to prefer the MIN_VERSION_ approach over a CABAL-flag approach for supporting multiple API versions of a dependent package (if both ways are possible)? And if not, when should I prefer which approach?
I'm not aware of any advantages of Cabal-flags over MIN_VERSION. If you use MIN_VERSION you can put :set -optP-include -optPdist/build/autogen/cabal_macros.h into a .ghci, and included it in the packages repository. That way you can use GHCi when developing on that package, without passing any CPP flags explicitly**. For that reason I prefer the MIN_VERSION-approach. Cheers, Simon ** An initial `cabal configure && cabal build` is still required, so that cabal_macros.h is generated.

On Tue, 18 Sep 2012, Herbert Valerio Riedel wrote:
Hello,
When I noticed the recently released HTTP-4000.2.5[1] package used a CABAL-flag based approach[2] for what I expected the use of a macro MIN_VERSION_network(2,4,0) to be more appropriate (see [3]), I wasn't totally sure whether there was any down-side with the MIN_VERSION_-approach. So my question is:
Is it always desirable to prefer the MIN_VERSION_ approach over a CABAL-flag approach for supporting multiple API versions of a dependent package (if both ways are possible)? And if not, when should I prefer which approach?
I prefer the Cabal approach since it requires one (hacky) tool less in the tool chain. I use different Hs-Source-Dirs depending on a Cabal flag. With ghci you can choose the different modules using the -i option.

On Tue, Sep 18, 2012 at 12:05 PM, Henning Thielemann
I prefer the Cabal approach since it requires one (hacky) tool less in the tool chain. I use different Hs-Source-Dirs depending on a Cabal flag. With ghci you can choose the different modules using the -i option.
I have sympathy with this argument in general, but in this particular case CPP is used anyway, so that's not much of an argument. Where CPP is unavoidable, I'd always prefer the MIN_VERSION_ macros for doing this job.

Henning Thielemann
I prefer the Cabal approach since it requires one (hacky) tool less in the tool chain. I use different Hs-Source-Dirs depending on a Cabal flag. With ghci you can choose the different modules using the -i option.
I see, but what about CABAL's version constraint solving algorithm: are there situations, where using the flag-based approach (to switch between disjunct version-ranges for a given dependency, thus requiring CABAL to backtrack on flag-settings iirc) leads to an observably different "solutions" than those which result when offering CABAL a contiguous version-range (and defer the version-range "discontinuity" to the CPP level)? Or are the two approaches "semantically" equivalent from the CABAL version constraint-solving point-of-view?

On 9/18/12 6:41 AM, Herbert Valerio Riedel wrote:
Hello,
When I noticed the recently released HTTP-4000.2.5[1] package used a CABAL-flag based approach[2] for what I expected the use of a macro MIN_VERSION_network(2,4,0) to be more appropriate (see [3]), I wasn't totally sure whether there was any down-side with the MIN_VERSION_-approach. So my question is:
Is it always desirable to prefer the MIN_VERSION_ approach over a CABAL-flag approach for supporting multiple API versions of a dependent package (if both ways are possible)? And if not, when should I prefer which approach?
If CPP is required, then I think it's preferable to use Cabal's MIN_VERSION macros; since, (1) Cabal can figure out the exact incantations for you, rather than foisting it upon users, and (2) it makes things more consistent across the Haskell ecosystem. However, the MIN_VERSION macros don't always work. In particular, they don't play nice with the hsc2hs preprocessor (and possibly other preprocessors as well). So in these cases one must resort to other hackery. -- Live well, ~wren

On 9/19/12 6:49 PM, wren ng thornton wrote:
On 9/18/12 6:41 AM, Herbert Valerio Riedel wrote:
Hello,
When I noticed the recently released HTTP-4000.2.5[1] package used a CABAL-flag based approach[2] for what I expected the use of a macro MIN_VERSION_network(2,4,0) to be more appropriate (see [3]), I wasn't totally sure whether there was any down-side with the MIN_VERSION_-approach. So my question is:
Is it always desirable to prefer the MIN_VERSION_ approach over a CABAL-flag approach for supporting multiple API versions of a dependent package (if both ways are possible)? And if not, when should I prefer which approach?
If CPP is required, then I think it's preferable to use Cabal's MIN_VERSION macros; since, (1) Cabal can figure out the exact incantations for you, rather than foisting it upon users, and (2) it makes things more consistent across the Haskell ecosystem.
However, the MIN_VERSION macros don't always work. In particular, they don't play nice with the hsc2hs preprocessor (and possibly other preprocessors as well). So in these cases one must resort to other hackery.
Oh, also, it's standard practice to use flags for dealing with the vagaries of what's in Base at any given moment. Though this is more for enabling Cabal conditionals, rather than for CPP stuff. -- Live well, ~wren
participants (5)
-
Ben Millwood
-
Henning Thielemann
-
Herbert Valerio Riedel
-
Simon Hengel
-
wren ng thornton