Re: MIN_VERSION macros
Hi all, I've implemented this: https://phabricator.haskell.org/D1349 Cheers, Edward Excerpts from Reid Barton's message of 2015-09-25 15:15:09 -0700: > On Fri, Sep 25, 2015 at 4:09 PM, Edward Z. Yangwrote: > > > Excerpts from Reid Barton's message of 2015-09-25 12:36:48 -0700: > > > GHC could provide MIN_VERSION_* macros for packages that have had their > > > versions specified with -package or similar flags (which is how Cabal > > > invokes GHC). That would go only a small way towards the original goals > > > though. > > > > This is exactly what the MIN_VERSION_* macros should do, and you can > > generalize it to work even without -package: you get macros for EXPOSED > > packages which are available for import. This says *nothing* about > > the transitive dependencies of the packages you're depending on, but > > it's more reasonable to have "one package, one version" invariant, > > because having multiple versions of the package exposed would cause > > a module name to be ambiguous (and unusable.) > > > Oh, I see. I had always assumed that GHC had some kind of solver to try to > pick compatible versions of packages, but having done some experiments, I > see that it always picks the newest exposed version of each direct > dependency. So we can indeed define MIN_VERSION_* macros in accordance with > the newest exposed version of each package. > > There are still some edge cases, notably: if package foo reexports the > contents of some modules from package bar, and the API of these modules > changes between two versions of package bar, then you cannot reliably use > MIN_VERSION_bar to detect these API changes in a module that imports the > reexports from package foo (since the newest installed foo might not be > built against the newest installed bar). In the more restrictive Cabal > model, you can reliably do this of course. So it could break in an existing > project. However this kind of situation (where the API of a package depends > on the version of its dependencies) should hopefully be fairly rare in > practice. > > Regards, > Reid Barton ___ ghc-devs mailing list ghc-devs@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs
MIN_VERSION macros
Cabal defines MIN_VERSION_* macros that allow CPP in a Haskell source file to get information about the versions of the packages that module is being compiled against. Unfortunately, these macros are not available when not compiling with cabal, so packages must either 1. Insist on cabal compilation. This is not very friendly to developers. 2. Make "pessimistic" assumptions, assuming that all the packages are old. This makes it annoying to test new features while also leading to compilation or run-time failures when packages have removed it changed features. 3. Attempt to guess the version based on the GHC version. This works reasonably well for base, ghc-prim, containers, etc., but not so well/at all for others. Would there be some way to get GHC itself to provide these macros to all modules that request CPP? David Feuer ___ ghc-devs mailing list ghc-devs@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs
Re: MIN_VERSION macros
I've been meaning to ask about this as well. It also forces tools like ghc-mod and hdevtools to be cabal-aware, which is an unnecessary source of complexity IMO. GHC certainly has enough information to generate these macros, as it knows which packages (and versions) it's compiling against. I think it's just a matter of adding the logic. I would love to see the MIN_VERSION macros moved to GHC. Eric On Fri, Sep 25, 2015, at 09:06, David Feuer wrote: > Cabal defines MIN_VERSION_* macros that allow CPP in a Haskell source > file > to get information about the versions of the packages that module is > being > compiled against. Unfortunately, these macros are not available when not > compiling with cabal, so packages must either > > 1. Insist on cabal compilation. This is not very friendly to developers. > 2. Make "pessimistic" assumptions, assuming that all the packages are > old. > This makes it annoying to test new features while also leading to > compilation or run-time failures when packages have removed it changed > features. > 3. Attempt to guess the version based on the GHC version. This works > reasonably well for base, ghc-prim, containers, etc., but not so well/at > all for others. > > Would there be some way to get GHC itself to provide these macros to all > modules that request CPP? > > David Feuer > ___ > ghc-devs mailing list > ghc-devs@haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs ___ ghc-devs mailing list ghc-devs@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs
Re: MIN_VERSION macros
On 2015-09-25 at 20:48:52 +0200, Richard Eisenberg wrote: > I've run into this issue, too. Post a feature request! I can't imagine > it's too hard to implement. For the current external CPP we'll probably have to create a temporary file with the definitions (just like cabal does) to -include (as afaik you can't easily pass function macros via `-D` to cpp). However, Anthony has mentioned he's working on an embeddable CPP impl over at https://www.reddit.com/r/haskell/comments/3m1wcs/call_for_nominations_haskell_prime_language/cvbp5ym which would allow to keep the currently in-scope MIN_VERSION_...() definitions in-memory w/o a temporary file. Finally, Cabal would have to be adapted to wrap the definitions with `#ifndef`s (or omit those altogether when calling a recent enough GHC) ___ ghc-devs mailing list ghc-devs@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs
Re: MIN_VERSION macros
On Fri, Sep 25, 2015 at 12:18 PM, Eric Seidelwrote: > I've been meaning to ask about this as well. It also forces tools like > ghc-mod and hdevtools to be cabal-aware, which is an unnecessary source > of complexity IMO. > This would certainly be nice, but... GHC certainly has enough information to generate these macros, as it > knows which packages (and versions) it's compiling against. > It knows at some point, but it doesn't necessarily know before parsing the module, at which point it is too late. I can have two versions of a package A, and two other packages B and C that depend on different versions of A, and depending on whether a module M uses package B or package C, M will see different versions of package A automatically. This is all slightly magical, and I have to say I don't entirely understand how GHC decides which versions to expose in general, but that's how GHC works today and it's quite convenient. GHC could provide MIN_VERSION_* macros for packages that have had their versions specified with -package or similar flags (which is how Cabal invokes GHC). That would go only a small way towards the original goals though. (Also, I wonder how MIN_VERSION_* fits into a Backpack world...) Regards, Reid Barton ___ ghc-devs mailing list ghc-devs@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs
Re: MIN_VERSION macros
I've run into this issue, too. Post a feature request! I can't imagine it's too hard to implement. Richard On Sep 25, 2015, at 12:18 PM, Eric Seidel <e...@seidel.io> wrote: > I've been meaning to ask about this as well. It also forces tools like > ghc-mod and hdevtools to be cabal-aware, which is an unnecessary source > of complexity IMO. > > GHC certainly has enough information to generate these macros, as it > knows which packages (and versions) it's compiling against. I think it's > just a matter of adding the logic. > > I would love to see the MIN_VERSION macros moved to GHC. > > Eric > > On Fri, Sep 25, 2015, at 09:06, David Feuer wrote: >> Cabal defines MIN_VERSION_* macros that allow CPP in a Haskell source >> file >> to get information about the versions of the packages that module is >> being >> compiled against. Unfortunately, these macros are not available when not >> compiling with cabal, so packages must either >> >> 1. Insist on cabal compilation. This is not very friendly to developers. >> 2. Make "pessimistic" assumptions, assuming that all the packages are >> old. >> This makes it annoying to test new features while also leading to >> compilation or run-time failures when packages have removed it changed >> features. >> 3. Attempt to guess the version based on the GHC version. This works >> reasonably well for base, ghc-prim, containers, etc., but not so well/at >> all for others. >> >> Would there be some way to get GHC itself to provide these macros to all >> modules that request CPP? >> >> David Feuer >> ___ >> ghc-devs mailing list >> ghc-devs@haskell.org >> http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs > ___ > ghc-devs mailing list > ghc-devs@haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs ___ ghc-devs mailing list ghc-devs@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs
Re: MIN_VERSION macros
Excerpts from Reid Barton's message of 2015-09-25 12:36:48 -0700: > It knows at some point, but it doesn't necessarily know before parsing the > module, at which point it is too late. I can have two versions of a package > A, and two other packages B and C that depend on different versions of A, > and depending on whether a module M uses package B or package C, M will see > different versions of package A automatically. This is all slightly > magical, and I have to say I don't entirely understand how GHC decides > which versions to expose in general, but that's how GHC works today and > it's quite convenient. Well, this is half true. The main "problem" is that GHC is actually a lot more flexible than Cabal's model allows: Cabal enforces that for any package, there is only one version of it in a program. But GHC can link any combination of packages (in GHC 7.8, it could link one instance of a package per package name and version; in GHC 7.10, it can link arbitrary instances together as long as they have distinct version names.) But I don't think this is a problem... > GHC could provide MIN_VERSION_* macros for packages that have had their > versions specified with -package or similar flags (which is how Cabal > invokes GHC). That would go only a small way towards the original goals > though. This is exactly what the MIN_VERSION_* macros should do, and you can generalize it to work even without -package: you get macros for EXPOSED packages which are available for import. This says *nothing* about the transitive dependencies of the packages you're depending on, but it's more reasonable to have "one package, one version" invariant, because having multiple versions of the package exposed would cause a module name to be ambiguous (and unusable.) > (Also, I wonder how MIN_VERSION_* fits into a Backpack world...) We have to support version bounds for BC, so... as well as BC can be :) Edward ___ ghc-devs mailing list ghc-devs@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs
Re: MIN_VERSION macros
On Fri, Sep 25, 2015 at 4:09 PM, Edward Z. Yangwrote: > Excerpts from Reid Barton's message of 2015-09-25 12:36:48 -0700: > > GHC could provide MIN_VERSION_* macros for packages that have had their > > versions specified with -package or similar flags (which is how Cabal > > invokes GHC). That would go only a small way towards the original goals > > though. > > This is exactly what the MIN_VERSION_* macros should do, and you can > generalize it to work even without -package: you get macros for EXPOSED > packages which are available for import. This says *nothing* about > the transitive dependencies of the packages you're depending on, but > it's more reasonable to have "one package, one version" invariant, > because having multiple versions of the package exposed would cause > a module name to be ambiguous (and unusable.) Oh, I see. I had always assumed that GHC had some kind of solver to try to pick compatible versions of packages, but having done some experiments, I see that it always picks the newest exposed version of each direct dependency. So we can indeed define MIN_VERSION_* macros in accordance with the newest exposed version of each package. There are still some edge cases, notably: if package foo reexports the contents of some modules from package bar, and the API of these modules changes between two versions of package bar, then you cannot reliably use MIN_VERSION_bar to detect these API changes in a module that imports the reexports from package foo (since the newest installed foo might not be built against the newest installed bar). In the more restrictive Cabal model, you can reliably do this of course. So it could break in an existing project. However this kind of situation (where the API of a package depends on the version of its dependencies) should hopefully be fairly rare in practice. Regards, Reid Barton ___ ghc-devs mailing list ghc-devs@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs