I agree that transitive dependency is a problem, and I suppose one that cannot 
even be fixed by sdist elaboration.


As a partial fix (which I believe would be acceptable for Edward) What if 
reexport wildcards were only permitted for modules that came from the local 
package? Since we have internal libraries, one might reasonably define a bunch 
of modules, and then in the same cabal file, want to reexport them from another 
internal library. If we take care in writing the error message, this 
restriction may not even be too hard for users to understand. I suppose if we 
take the theme from your suggestion, which is Cabal files as honest to goodness 
programs, this would be equivalent to being able to define module lists and 
then reuse them elsewhere (perhaps after some string processing; similar to 
common stanzas).


As a more general thought: I noticed in a few other situations where 
traditional PVP does a poor job at addressing situations where API stability 
depends on packages you yourself depend on. For example, let's say I wanted to 
make a metapackage that took a few packages and reexported their modules. You 
don't even have to talk about the module level: at the declaration level, what 
identifiers are available from this package will depend on the version choices 
of its dependencies. But it's infeasible to publish combinatorially many 
versions of the metapackage for each possible version of its dependency; 
instead, you'd rather just say that the API of this package depends not only on 
the package itself, but also some other subpackages. Without some expressivity 
like this, you just can't write packages like this.


Edward



________________________________
From: cabal-devel <cabal-devel-boun...@haskell.org> on behalf of Oleg Grenrus 
<oleg.gren...@iki.fi>
Sent: Thursday, February 25, 2021 2:01 PM
To: cabal-devel@haskell.org
Subject: Re: [RFC] Qualified module renamings


How this will work with packages adding modules.

For concrete example:

- parsec-backpack-0.1 provides two modules Parsec.Prim and Parsec.Combinators
- in my library, I instantiate Parsec.* to Parsec.Text.*, and Parsec.String.*, 
I get four modules. That is nice.
- parsec-backpack-0.1.1 is released adding Parsec.Error. I get six modules. 
That is still fine as they are not exported.

However, if the same example is done for re-exported modules, my library public 
interface would change depending on (minor) version of a dependency. This is no 
go in Hackage context.

As far as I can see it, reexported-modules and wildcards are no go.

Something like

    reexported-modules: [ [ Parsec.Text.m, Parsec.String.m] | m <- [ Prim, 
Combinators ] ]

or

    reexported-modules: for m in [Prim, Combinators]: Parsec.Text.m, 
Parsec.String.m

or some variation of that idea which fits cabal/module syntax would be both 
explicit and still more convenient.

I also think it will be even easier to implement, as you all information is 
there, you don't need to know any context to expand it.

- Oleg


On 25.2.2021 23.01, Edward Z Yang wrote:

> It took me about five minutes to arrive at the guess that this is about the 
> syntax in Cabal files for using backpack - is that right?


Oops yes, sorry for omitting this context.


> What is the intent of what got implemented, anyway? Are there example use 
> cases?


I'm not exactly sure what you mean by intent. But a common pattern in Backpack 
is to instantiate a library multiple time with different requirements, and if 
you want them all in scope you have to rename them. Right now, this has to be 
done one-by-one for each provided module, which can be a bit annoying. For 
example, let say you parametrized parsec by string type, and you wanted a 
bytestring version and a text version, it would be convenient to be able to 
unconditionally rename every Text.Parsec.* module to Text.Parsec.*.ByteString 
(for example)


Edward Kmett described a concrete motivating use case at 
https://github.com/haskell/cabal/issues/7290#issuecomment-783540208? although 
his use case is a little difficult to understand.


Edward


________________________________
From: Bryan Richter <b...@chreekat.net><mailto:b...@chreekat.net>
Sent: Thursday, February 25, 2021 10:06 AM
To: Edward Z Yang
Cc: cabal-devel@haskell.org<mailto:cabal-devel@haskell.org>; 
ekm...@gmail.com<mailto:ekm...@gmail.com>
Subject: Re: [RFC] Qualified module renamings

It took me about five minutes to arrive at the guess that this is about the 
syntax in Cabal files for using backpack - is that right?

What is the intent of what got implemented, anyway? Are there example use cases?

Den tors 25 feb. 2021 18:14Edward Z Yang 
<ezy...@mit.edu<mailto:ezy...@mit.edu>> skrev:

Today, using the 'mixins' field you can rename modules that come from other 
packages by manually expressing a renaming one-by-one. In some Backpack use 
cases, you may have a lot of modules that you would like to mechanically rename 
into some subnamespace; today, you have manually list each renaming one by one.


https://github.com/haskell/cabal/pull/7303 contains an implementation of one 
possible way to extend mixin syntax to support qualified renaming; the 
implementation is very simple. The syntax here is based off of Richard 
Eisenberg's local modules proposal 
(https://github.com/ghc-proposals/ghc-proposals/pull/283) which supports the 
qualified keyword before module exports/imports which has the same effect 
(bring the module into scope under a sub-module namespace). However, the PR 
isn't really meant to be an end all to the discussion: it's just to show that 
it's pretty simple to implement this functionality.


There are two primary axes which I am looking for feedback:


* Expressivity. The current PoC implementation only permits unconditionally 
prefix-ing all modules that would have been brought into scope by the mixin; 
e.g., transforming module A to Prefix.A. Edward Kmett has expressed that in 
some cases, he would like it if you could implement the import as a suffix. One 
could also imagine allowing arbitrary string transformations. Opinions on where 
to draw the line for expressivity are solicited.


* Syntax. The current syntax is "pkgname qualified Prefix" as it is symmetric 
with "pkgname hiding (A, B)" and it was simple to implement. But I am not 
particularly attached to this syntax, and am open to other suggestions. If we 
permit suffixing, a wildcard based syntax like "pkgname (* as *.Suffix)" may be 
preferable (though modestly more complex to specify and implement; for example, 
is the glob recursive over dots?). Edward Kmett has offered some other 
possibilities at https://github.com/haskell/cabal/issues/7290#issue-812744575?


Thanks Oleg for reminding me to send this RFC to this mailing list.


Cheers,

Edward

_______________________________________________
cabal-devel mailing list
cabal-devel@haskell.org<mailto:cabal-devel@haskell.org>
http://mail.haskell.org/cgi-bin/mailman/listinfo/cabal-devel



_______________________________________________
cabal-devel mailing list
cabal-devel@haskell.org<mailto:cabal-devel@haskell.org>
http://mail.haskell.org/cgi-bin/mailman/listinfo/cabal-devel

_______________________________________________
cabal-devel mailing list
cabal-devel@haskell.org
http://mail.haskell.org/cgi-bin/mailman/listinfo/cabal-devel

Reply via email to