#283: Local modules (again), recommendation: accept

Dear all, It is time to review the local modules proposal, from our own Richard Eisenberg, again. In fact it’s been time for a while, and I must apologise to Richard for not having understood that. Sorry, Richard. Link: https://github.com/ghc-proposals/ghc-proposals/pull/283 Since the last time, the proposal has been both simplified and made more precise. The main issues solved by this proposal are - The ability to export qualified names from modules - The ability to define functions with qualified names within a module ( *e.g.* you could have both T.f and U.f). - The ability to locally refer to qualified data as unqualified (suppose Set.map is in scope, then the proposal lets you write let import module Set in map f (map g some_set). I think these are three important issues, and the proposal makes a good case that they ought to be solved together. I also think that the specification is clear and doesn’t leave any dark corner. Caveat: I have contributed to writing the current specification, so I may be missing some flaws. The proposal does introduce a somewhat byzantine semantic difference between module X and module qualified X in export lists. This is to keep the current meaning of module X which is already not very intuitive (cf https://ro-che.info/articles/2012-12-25-haskell-module-system-p1 ). I think this is unavoidable. There are also 3 optional pieces of specification that we are asked to rule on (§4). I’m personally in favour of option 1. I’m weakly in favour of option 3 (with a preference for the variant described in Alternative 7). On the other hand option 2 seems to add a bit too much syntactic subtlety to be worth it (though if we choose option 2, I see no reason not to accept Alternative 3 as well). /Arnaud

Dear all,
I am in favor of this proposal. I think it solves one important issue in
Haskell’s design (I’ve always hated the 1-1 relationship between modules
and files), and does so in a way which feels natural with the rest of the
language.
Regarding the optional pieces of the spec:
- I am not sure of the benefit of allowing (1), compared with the possible
surprise of users.
- I do not fully understand (2).
- I think (3) would be great, if we ensure that nothing changes if I don’t
use “qualified”, even if -XLocalModules is on.
Regards,
Alejandro
El 20 may 2021 17:42:30, Spiwack, Arnaud
Dear all,
It is time to review the local modules proposal, from our own Richard Eisenberg, again. In fact it’s been time for a while, and I must apologise to Richard for not having understood that. Sorry, Richard.
Link: https://github.com/ghc-proposals/ghc-proposals/pull/283
Since the last time, the proposal has been both simplified and made more precise. The main issues solved by this proposal are
- The ability to export qualified names from modules - The ability to define functions with qualified names within a module (*e.g.* you could have both T.f and U.f). - The ability to locally refer to qualified data as unqualified (suppose Set.map is in scope, then the proposal lets you write let import module Set in map f (map g some_set).
I think these are three important issues, and the proposal makes a good case that they ought to be solved together. I also think that the specification is clear and doesn’t leave any dark corner. Caveat: I have contributed to writing the current specification, so I may be missing some flaws.
The proposal does introduce a somewhat byzantine semantic difference between module X and module qualified X in export lists. This is to keep the current meaning of module X which is already not very intuitive (cf https://ro-che.info/articles/2012-12-25-haskell-module-system-p1 ). I think this is unavoidable.
There are also 3 optional pieces of specification that we are asked to rule on (§4). I’m personally in favour of option 1. I’m weakly in favour of option 3 (with a preference for the variant described in Alternative 7). On the other hand option 2 seems to add a bit too much syntactic subtlety to be worth it (though if we choose option 2, I see no reason not to accept Alternative 3 as well).
/Arnaud _______________________________________________ ghc-steering-committee mailing list ghc-steering-committee@haskell.org https://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-steering-committee

On May 25, 2021, at 3:09 PM, Alejandro Serrano Mena
wrote: - I am not sure of the benefit of allowing (1), compared with the possible surprise of users. - I do not fully understand (2). - I think (3) would be great, if we ensure that nothing changes if I don’t use “qualified”, even if -XLocalModules is on.
If in the language, I would use (1) -- anonymous local modules -- regularly, when defining a function or class instance with a bunch of "local" helper functions. Of course, if we can't omit the module name, I will suffer no great harm. I cannot offer the guarantee you seek in (3), but I don't think you want it. (If nothing changes, then the feature has no effect!) Here is a scenario where (3) could cause trouble:
import Data.Set as Set ( abcde )
data Set = Mk { abcdf :: Int }
blah = Set.abcdf
Previously, GHC would have suggested that you perhaps misspelled abcde. Now, you'll get (presumably) a type error. Here's another case:
import Data.Set as Set ( Set )
data Set = Mk
x :: Set.Set
Everything is happy today, but with -XLocalModules (and (3)), the type of x is an ambiguous name. Any example that causes trouble, though, will have something in common: an imported module name (possibly via an alias) that matches a locally defined type name. I would imagine this pattern is rare in practice, and that the benefit of (3) would outweigh the number of times that a problem like this bites. I, too, could live without (2). Richard

I'm realising that I inverted additional options 1 and 3 in my reply. To
spell things out: I'm in favour of the namespace introduced for every
datatype and such; and weakly in favour of anonymous modules, for which I
prefer the `_` syntax than simply omitting the name.
On Tue, May 25, 2021 at 11:54 PM Richard Eisenberg
On May 25, 2021, at 3:09 PM, Alejandro Serrano Mena
wrote: - I am not sure of the benefit of allowing (1), compared with the possible surprise of users. - I do not fully understand (2). - I think (3) would be great, if we ensure that nothing changes if I don’t use “qualified”, even if -XLocalModules is on.
If in the language, I would use (1) -- anonymous local modules -- regularly, when defining a function or class instance with a bunch of "local" helper functions. Of course, if we can't omit the module name, I will suffer no great harm.
I cannot offer the guarantee you seek in (3), but I don't think you want it. (If nothing changes, then the feature has no effect!) Here is a scenario where (3) could cause trouble:
import Data.Set as Set ( abcde )
data Set = Mk { abcdf :: Int }
blah = Set.abcdf
Previously, GHC would have suggested that you perhaps misspelled abcde. Now, you'll get (presumably) a type error.
Here's another case:
import Data.Set as Set ( Set )
data Set = Mk
x :: Set.Set
Everything is happy today, but with -XLocalModules (and (3)), the type of x is an ambiguous name.
Any example that causes trouble, though, will have something in common: an imported module name (possibly via an alias) that matches a locally defined type name. I would imagine this pattern is rare in practice, and that the benefit of (3) would outweigh the number of times that a problem like this bites.
I, too, could live without (2).
Richard

On May 26, 2021, at 3:28 AM, Spiwack, Arnaud
wrote: I'm realising that I inverted additional options 1 and 3 in my reply. To spell things out: I'm in favour of the namespace introduced for every datatype and such; and weakly in favour of anonymous modules, for which I prefer the `_` syntax than simply omitting the name.
Oh, good. I was very confused here, but I decided not to push on it. I'm similarly weakly in favor of (1), but I can't get myself to decide firmly on whether to go with alternative (7). Going with (7) is a little more consistent with other features, but it adds more symbols to the source text that could otherwise be omitted. So I'm pretty ambivalent. Richard
On Tue, May 25, 2021 at 11:54 PM Richard Eisenberg
mailto:rae@richarde.dev> wrote: On May 25, 2021, at 3:09 PM, Alejandro Serrano Mena
mailto:trupill@gmail.com> wrote: - I am not sure of the benefit of allowing (1), compared with the possible surprise of users. - I do not fully understand (2). - I think (3) would be great, if we ensure that nothing changes if I don’t use “qualified”, even if -XLocalModules is on.
If in the language, I would use (1) -- anonymous local modules -- regularly, when defining a function or class instance with a bunch of "local" helper functions. Of course, if we can't omit the module name, I will suffer no great harm.
I cannot offer the guarantee you seek in (3), but I don't think you want it. (If nothing changes, then the feature has no effect!) Here is a scenario where (3) could cause trouble:
import Data.Set as Set ( abcde )
data Set = Mk { abcdf :: Int }
blah = Set.abcdf
Previously, GHC would have suggested that you perhaps misspelled abcde. Now, you'll get (presumably) a type error.
Here's another case:
import Data.Set as Set ( Set )
data Set = Mk
x :: Set.Set
Everything is happy today, but with -XLocalModules (and (3)), the type of x is an ambiguous name.
Any example that causes trouble, though, will have something in common: an imported module name (possibly via an alias) that matches a locally defined type name. I would imagine this pattern is rare in practice, and that the benefit of (3) would outweigh the number of times that a problem like this bites.
I, too, could live without (2).
Richard

Dear all,
Let me raise this proposal again. Very few of us have opined, and while I'd
usually be happy to consider silence as assent, this is a rather large
proposal which may require a few more pairs of eyes. Please consider giving
this one a read and share your thoughts. If you can't do so right now,
please let me know when you will be able to, so that we can plan
accordingly.
This is an important proposal, I'm keen on seeing its design finalised.
/Arnaud
On Wed, May 26, 2021 at 2:35 PM Richard Eisenberg
On May 26, 2021, at 3:28 AM, Spiwack, Arnaud
wrote: I'm realising that I inverted additional options 1 and 3 in my reply. To spell things out: I'm in favour of the namespace introduced for every datatype and such; and weakly in favour of anonymous modules, for which I prefer the `_` syntax than simply omitting the name.
Oh, good. I was very confused here, but I decided not to push on it. I'm similarly weakly in favor of (1), but I can't get myself to decide firmly on whether to go with alternative (7). Going with (7) is a little more consistent with other features, but it adds more symbols to the source text that could otherwise be omitted. So I'm pretty ambivalent.
Richard
On Tue, May 25, 2021 at 11:54 PM Richard Eisenberg
wrote: On May 25, 2021, at 3:09 PM, Alejandro Serrano Mena
wrote: - I am not sure of the benefit of allowing (1), compared with the possible surprise of users. - I do not fully understand (2). - I think (3) would be great, if we ensure that nothing changes if I don’t use “qualified”, even if -XLocalModules is on.
If in the language, I would use (1) -- anonymous local modules -- regularly, when defining a function or class instance with a bunch of "local" helper functions. Of course, if we can't omit the module name, I will suffer no great harm.
I cannot offer the guarantee you seek in (3), but I don't think you want it. (If nothing changes, then the feature has no effect!) Here is a scenario where (3) could cause trouble:
import Data.Set as Set ( abcde )
data Set = Mk { abcdf :: Int }
blah = Set.abcdf
Previously, GHC would have suggested that you perhaps misspelled abcde. Now, you'll get (presumably) a type error.
Here's another case:
import Data.Set as Set ( Set )
data Set = Mk
x :: Set.Set
Everything is happy today, but with -XLocalModules (and (3)), the type of x is an ambiguous name.
Any example that causes trouble, though, will have something in common: an imported module name (possibly via an alias) that matches a locally defined type name. I would imagine this pattern is rare in practice, and that the benefit of (3) would outweigh the number of times that a problem like this bites.
I, too, could live without (2).
Richard

Any thoughts on this? Simon PJ seems lukewarm (or maybe even cooler than that), Arnaud is in support, but the rest of you have been quiet. Thanks! Richard
On Jun 11, 2021, at 3:05 AM, Spiwack, Arnaud
wrote: Dear all,
Let me raise this proposal again. Very few of us have opined, and while I'd usually be happy to consider silence as assent, this is a rather large proposal which may require a few more pairs of eyes. Please consider giving this one a read and share your thoughts. If you can't do so right now, please let me know when you will be able to, so that we can plan accordingly.
This is an important proposal, I'm keen on seeing its design finalised.
/Arnaud
On Wed, May 26, 2021 at 2:35 PM Richard Eisenberg
mailto:rae@richarde.dev> wrote: On May 26, 2021, at 3:28 AM, Spiwack, Arnaud
mailto:arnaud.spiwack@tweag.io> wrote: I'm realising that I inverted additional options 1 and 3 in my reply. To spell things out: I'm in favour of the namespace introduced for every datatype and such; and weakly in favour of anonymous modules, for which I prefer the `_` syntax than simply omitting the name.
Oh, good. I was very confused here, but I decided not to push on it. I'm similarly weakly in favor of (1), but I can't get myself to decide firmly on whether to go with alternative (7). Going with (7) is a little more consistent with other features, but it adds more symbols to the source text that could otherwise be omitted. So I'm pretty ambivalent.
Richard
On Tue, May 25, 2021 at 11:54 PM Richard Eisenberg
mailto:rae@richarde.dev> wrote: On May 25, 2021, at 3:09 PM, Alejandro Serrano Mena
mailto:trupill@gmail.com> wrote: - I am not sure of the benefit of allowing (1), compared with the possible surprise of users. - I do not fully understand (2). - I think (3) would be great, if we ensure that nothing changes if I don’t use “qualified”, even if -XLocalModules is on.
If in the language, I would use (1) -- anonymous local modules -- regularly, when defining a function or class instance with a bunch of "local" helper functions. Of course, if we can't omit the module name, I will suffer no great harm.
I cannot offer the guarantee you seek in (3), but I don't think you want it. (If nothing changes, then the feature has no effect!) Here is a scenario where (3) could cause trouble:
import Data.Set as Set ( abcde )
data Set = Mk { abcdf :: Int }
blah = Set.abcdf
Previously, GHC would have suggested that you perhaps misspelled abcde. Now, you'll get (presumably) a type error.
Here's another case:
import Data.Set as Set ( Set )
data Set = Mk
x :: Set.Set
Everything is happy today, but with -XLocalModules (and (3)), the type of x is an ambiguous name.
Any example that causes trouble, though, will have something in common: an imported module name (possibly via an alias) that matches a locally defined type name. I would imagine this pattern is rare in practice, and that the benefit of (3) would outweigh the number of times that a problem like this bites.
I, too, could live without (2).
Richard

I am morally sympathetic to the overall goal, but didn't find the time to scrutinize the details. Usually in that case I hope that the other committee members due the due diligence and hope I can just follow along. Is that helpful?

I may well have said this before, but I’m enthusiastically in support of this proposal. In fact the first five motivating examples are things I could use regularly. I particularly like the `import Foo ( Foo, module Foo )` idiom, as it will almost halve the import blocks I have at the moment. Not sure that I can add much beyond what has already been discussed here, other than to say it’s a +1 from me! Thanks, Tom
On 20 Jul 2021, at 07:19, Joachim Breitner
wrote: I am morally sympathetic to the overall goal, but didn't find the time to scrutinize the details. Usually in that case I hope that the other committee members due the due diligence and hope I can just follow along. Is that helpful? _______________________________________________ ghc-steering-committee mailing list ghc-steering-committee@haskell.org https://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-steering-committee

To be clear, I’m ok with (1), luke-warm on (2), and mildly against (3)
1. Import and export of qualified names. This seems like the Main Point.
2. Local import (in a let/where). This seems low pain but low gain.
3. Local modules. This is the one I'm struggling with.
There is more on the (tail end of the) PR https://github.com/ghc-proposals/ghc-proposals/pull/283
I am open to being educated.
I would love to hear from other members of the committee. Tom’s thumbs-up seemed to about (1), without saying anything about (2) and (3).
One mechanism (if my categorisation is correct) could be to ask everyone to vote (yes/no/maybe) on all of 1,2,3.
Arnaud, you are our shepherd. Your sheep await your command.
Simon
From: ghc-steering-committee

Dear all,
I know that this proposal is a bit long, but it also deserves your
attention.
I feel it's going to be easier to set a bit of time to review the proposal
if I give a deadline. So let's say the following: I'll be on holiday
starting two weeks from now (6th August), can I have everybody's opinion by
then?
---
Recapitulating the opinions so far
- I'm personally pretty enthusiastic about the entire proposal
- Tom voiced quite enthusiastic support for what Simon PJ calls (1), and
(3)
- Simon PJ wants (1), is not against (2), is mildly against (3)
- Joachim suspends his judgement (which is fine, but hopefully not too
many of us do this :-) ).
On Wed, Jul 21, 2021 at 2:30 PM Simon Peyton Jones
To be clear, I’m ok with (1), luke-warm on (2), and mildly against (3)
1. Import and export of qualified names. This seems like the Main Point. 2. Local import (in a let/where). This seems low pain but low gain. 3. Local modules. This is the one I'm struggling with.
There is more on the (tail end of the) PR https://github.com/ghc-proposals/ghc-proposals/pull/283
I am open to being educated.
I would love to hear from other members of the committee. Tom’s thumbs-up seemed to about (1), without saying anything about (2) and (3).
One mechanism (if my categorisation is correct) could be to ask everyone to vote (yes/no/maybe) on all of 1,2,3.
Arnaud, you are our shepherd. Your sheep await your command.
Simon
*From:* ghc-steering-committee
*On Behalf Of *Richard Eisenberg *Sent:* 19 July 2021 21:18 *To:* Spiwack, Arnaud *Cc:* GHC Steering Committee *Subject:* Re: [ghc-steering-committee] #283: Local modules (again), recommendation: accept Any thoughts on this? Simon PJ seems lukewarm (or maybe even cooler than that), Arnaud is in support, but the rest of you have been quiet.
Thanks!
Richard
On Jun 11, 2021, at 3:05 AM, Spiwack, Arnaud
wrote: Dear all,
Let me raise this proposal again. Very few of us have opined, and while I'd usually be happy to consider silence as assent, this is a rather large proposal which may require a few more pairs of eyes. Please consider giving this one a read and share your thoughts. If you can't do so right now, please let me know when you will be able to, so that we can plan accordingly.
This is an important proposal, I'm keen on seeing its design finalised.
/Arnaud
On Wed, May 26, 2021 at 2:35 PM Richard Eisenberg
wrote: On May 26, 2021, at 3:28 AM, Spiwack, Arnaud
wrote: I'm realising that I inverted additional options 1 and 3 in my reply. To spell things out: I'm in favour of the namespace introduced for every datatype and such; and weakly in favour of anonymous modules, for which I prefer the `_` syntax than simply omitting the name.
Oh, good. I was very confused here, but I decided not to push on it. I'm similarly weakly in favor of (1), but I can't get myself to decide firmly on whether to go with alternative (7). Going with (7) is a little more consistent with other features, but it adds more symbols to the source text that could otherwise be omitted. So I'm pretty ambivalent.
Richard
On Tue, May 25, 2021 at 11:54 PM Richard Eisenberg
wrote: On May 25, 2021, at 3:09 PM, Alejandro Serrano Mena
wrote: - I am not sure of the benefit of allowing (1), compared with the possible surprise of users.
- I do not fully understand (2).
- I think (3) would be great, if we ensure that nothing changes if I don’t use “qualified”, even if -XLocalModules is on.
If in the language, I would use (1) -- anonymous local modules -- regularly, when defining a function or class instance with a bunch of "local" helper functions. Of course, if we can't omit the module name, I will suffer no great harm.
I cannot offer the guarantee you seek in (3), but I don't think you want it. (If nothing changes, then the feature has no effect!) Here is a scenario where (3) could cause trouble:
import Data.Set as Set ( abcde )
data Set = Mk { abcdf :: Int }
blah = Set.abcdf
Previously, GHC would have suggested that you perhaps misspelled abcde. Now, you'll get (presumably) a type error.
Here's another case:
import Data.Set as Set ( Set )
data Set = Mk
x :: Set.Set
Everything is happy today, but with -XLocalModules (and (3)), the type of x is an ambiguous name.
Any example that causes trouble, though, will have something in common: an imported module name (possibly via an alias) that matches a locally defined type name. I would imagine this pattern is rare in practice, and that the benefit of (3) would outweigh the number of times that a problem like this bites.
I, too, could live without (2).
Richard

Just so I'm not completely silent: in the past I was generally in favour
but had some suggestions. It looks like the proposal has undergone a lot of
rewrites since I last reviewed it (or perhaps I just don't remember it all
that well), I've started to go through it again but this is a biggie!
I think a deadline is a good idea.
Cheers
Simon
On Fri, 23 Jul 2021 at 07:23, Spiwack, Arnaud
Dear all,
I know that this proposal is a bit long, but it also deserves your attention.
I feel it's going to be easier to set a bit of time to review the proposal if I give a deadline. So let's say the following: I'll be on holiday starting two weeks from now (6th August), can I have everybody's opinion by then?
---
Recapitulating the opinions so far
- I'm personally pretty enthusiastic about the entire proposal - Tom voiced quite enthusiastic support for what Simon PJ calls (1), and (3) - Simon PJ wants (1), is not against (2), is mildly against (3) - Joachim suspends his judgement (which is fine, but hopefully not too many of us do this :-) ).
On Wed, Jul 21, 2021 at 2:30 PM Simon Peyton Jones
wrote: To be clear, I’m ok with (1), luke-warm on (2), and mildly against (3)
1. Import and export of qualified names. This seems like the Main Point. 2. Local import (in a let/where). This seems low pain but low gain. 3. Local modules. This is the one I'm struggling with.
There is more on the (tail end of the) PR https://github.com/ghc-proposals/ghc-proposals/pull/283
I am open to being educated.
I would love to hear from other members of the committee. Tom’s thumbs-up seemed to about (1), without saying anything about (2) and (3).
One mechanism (if my categorisation is correct) could be to ask everyone to vote (yes/no/maybe) on all of 1,2,3.
Arnaud, you are our shepherd. Your sheep await your command.
Simon
*From:* ghc-steering-committee < ghc-steering-committee-bounces@haskell.org> *On Behalf Of *Richard Eisenberg *Sent:* 19 July 2021 21:18 *To:* Spiwack, Arnaud
*Cc:* GHC Steering Committee *Subject:* Re: [ghc-steering-committee] #283: Local modules (again), recommendation: accept Any thoughts on this? Simon PJ seems lukewarm (or maybe even cooler than that), Arnaud is in support, but the rest of you have been quiet.
Thanks!
Richard
On Jun 11, 2021, at 3:05 AM, Spiwack, Arnaud
wrote: Dear all,
Let me raise this proposal again. Very few of us have opined, and while I'd usually be happy to consider silence as assent, this is a rather large proposal which may require a few more pairs of eyes. Please consider giving this one a read and share your thoughts. If you can't do so right now, please let me know when you will be able to, so that we can plan accordingly.
This is an important proposal, I'm keen on seeing its design finalised.
/Arnaud
On Wed, May 26, 2021 at 2:35 PM Richard Eisenberg
wrote: On May 26, 2021, at 3:28 AM, Spiwack, Arnaud
wrote: I'm realising that I inverted additional options 1 and 3 in my reply. To spell things out: I'm in favour of the namespace introduced for every datatype and such; and weakly in favour of anonymous modules, for which I prefer the `_` syntax than simply omitting the name.
Oh, good. I was very confused here, but I decided not to push on it. I'm similarly weakly in favor of (1), but I can't get myself to decide firmly on whether to go with alternative (7). Going with (7) is a little more consistent with other features, but it adds more symbols to the source text that could otherwise be omitted. So I'm pretty ambivalent.
Richard
On Tue, May 25, 2021 at 11:54 PM Richard Eisenberg
wrote: On May 25, 2021, at 3:09 PM, Alejandro Serrano Mena
wrote: - I am not sure of the benefit of allowing (1), compared with the possible surprise of users.
- I do not fully understand (2).
- I think (3) would be great, if we ensure that nothing changes if I don’t use “qualified”, even if -XLocalModules is on.
If in the language, I would use (1) -- anonymous local modules -- regularly, when defining a function or class instance with a bunch of "local" helper functions. Of course, if we can't omit the module name, I will suffer no great harm.
I cannot offer the guarantee you seek in (3), but I don't think you want it. (If nothing changes, then the feature has no effect!) Here is a scenario where (3) could cause trouble:
import Data.Set as Set ( abcde )
data Set = Mk { abcdf :: Int }
blah = Set.abcdf
Previously, GHC would have suggested that you perhaps misspelled abcde. Now, you'll get (presumably) a type error.
Here's another case:
import Data.Set as Set ( Set )
data Set = Mk
x :: Set.Set
Everything is happy today, but with -XLocalModules (and (3)), the type of x is an ambiguous name.
Any example that causes trouble, though, will have something in common: an imported module name (possibly via an alias) that matches a locally defined type name. I would imagine this pattern is rare in practice, and that the benefit of (3) would outweigh the number of times that a problem like this bites.
I, too, could live without (2).
Richard
_______________________________________________ ghc-steering-committee mailing list ghc-steering-committee@haskell.org https://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-steering-committee

Re-reading the thread has made me aware of the distinction introduced by
this proposal between “top-level” and “local modules”, which I do not fully
grasp. I was under the impression that this was working more on the
syntactic level (so if I write `module X where module Y where` this is
similar to `module X.Y where`), and the specification was about sorting out
how this works, but now I’m surprised about this new concept.
Regards,
Alejandro
El 23 jul 2021 12:00:40, Simon Marlow
Just so I'm not completely silent: in the past I was generally in favour but had some suggestions. It looks like the proposal has undergone a lot of rewrites since I last reviewed it (or perhaps I just don't remember it all that well), I've started to go through it again but this is a biggie!
I think a deadline is a good idea.
Cheers Simon
On Fri, 23 Jul 2021 at 07:23, Spiwack, Arnaud
wrote: Dear all,
I know that this proposal is a bit long, but it also deserves your attention.
I feel it's going to be easier to set a bit of time to review the proposal if I give a deadline. So let's say the following: I'll be on holiday starting two weeks from now (6th August), can I have everybody's opinion by then?
---
Recapitulating the opinions so far
- I'm personally pretty enthusiastic about the entire proposal - Tom voiced quite enthusiastic support for what Simon PJ calls (1), and (3) - Simon PJ wants (1), is not against (2), is mildly against (3) - Joachim suspends his judgement (which is fine, but hopefully not too many of us do this :-) ).
On Wed, Jul 21, 2021 at 2:30 PM Simon Peyton Jones
wrote: To be clear, I’m ok with (1), luke-warm on (2), and mildly against (3)
1. Import and export of qualified names. This seems like the Main Point. 2. Local import (in a let/where). This seems low pain but low gain. 3. Local modules. This is the one I'm struggling with.
There is more on the (tail end of the) PR https://github.com/ghc-proposals/ghc-proposals/pull/283
I am open to being educated.
I would love to hear from other members of the committee. Tom’s thumbs-up seemed to about (1), without saying anything about (2) and (3).
One mechanism (if my categorisation is correct) could be to ask everyone to vote (yes/no/maybe) on all of 1,2,3.
Arnaud, you are our shepherd. Your sheep await your command.
Simon
*From:* ghc-steering-committee < ghc-steering-committee-bounces@haskell.org> *On Behalf Of *Richard Eisenberg *Sent:* 19 July 2021 21:18 *To:* Spiwack, Arnaud
*Cc:* GHC Steering Committee *Subject:* Re: [ghc-steering-committee] #283: Local modules (again), recommendation: accept Any thoughts on this? Simon PJ seems lukewarm (or maybe even cooler than that), Arnaud is in support, but the rest of you have been quiet.
Thanks!
Richard
On Jun 11, 2021, at 3:05 AM, Spiwack, Arnaud
wrote: Dear all,
Let me raise this proposal again. Very few of us have opined, and while I'd usually be happy to consider silence as assent, this is a rather large proposal which may require a few more pairs of eyes. Please consider giving this one a read and share your thoughts. If you can't do so right now, please let me know when you will be able to, so that we can plan accordingly.
This is an important proposal, I'm keen on seeing its design finalised.
/Arnaud
On Wed, May 26, 2021 at 2:35 PM Richard Eisenberg
wrote: On May 26, 2021, at 3:28 AM, Spiwack, Arnaud
wrote: I'm realising that I inverted additional options 1 and 3 in my reply. To spell things out: I'm in favour of the namespace introduced for every datatype and such; and weakly in favour of anonymous modules, for which I prefer the `_` syntax than simply omitting the name.
Oh, good. I was very confused here, but I decided not to push on it. I'm similarly weakly in favor of (1), but I can't get myself to decide firmly on whether to go with alternative (7). Going with (7) is a little more consistent with other features, but it adds more symbols to the source text that could otherwise be omitted. So I'm pretty ambivalent.
Richard
On Tue, May 25, 2021 at 11:54 PM Richard Eisenberg
wrote: On May 25, 2021, at 3:09 PM, Alejandro Serrano Mena
wrote: - I am not sure of the benefit of allowing (1), compared with the possible surprise of users.
- I do not fully understand (2).
- I think (3) would be great, if we ensure that nothing changes if I don’t use “qualified”, even if -XLocalModules is on.
If in the language, I would use (1) -- anonymous local modules -- regularly, when defining a function or class instance with a bunch of "local" helper functions. Of course, if we can't omit the module name, I will suffer no great harm.
I cannot offer the guarantee you seek in (3), but I don't think you want it. (If nothing changes, then the feature has no effect!) Here is a scenario where (3) could cause trouble:
import Data.Set as Set ( abcde )
data Set = Mk { abcdf :: Int }
blah = Set.abcdf
Previously, GHC would have suggested that you perhaps misspelled abcde. Now, you'll get (presumably) a type error.
Here's another case:
import Data.Set as Set ( Set )
data Set = Mk
x :: Set.Set
Everything is happy today, but with -XLocalModules (and (3)), the type of x is an ambiguous name.
Any example that causes trouble, though, will have something in common: an imported module name (possibly via an alias) that matches a locally defined type name. I would imagine this pattern is rare in practice, and that the benefit of (3) would outweigh the number of times that a problem like this bites.
I, too, could live without (2).
Richard
_______________________________________________ ghc-steering-committee mailing list ghc-steering-committee@haskell.org https://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-steering-committee
_______________________________________________ ghc-steering-committee mailing list ghc-steering-committee@haskell.org https://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-steering-committee

Hi Alejandro, This distinction between top-level module and local module is pretty superficial. I've added a new bit to the proposal to explain this:
This proposal describes top-level modules as distinct from local modules, but this distinction has little import. Here is the full set of differences between these concepts:
The module keyword for a top-level module is the first lexeme in a file; the module keyword for a local module must not be the first lexeme in a file. A top-level module can have import statements; a local module can have only import module statements. An import statement can name only a top-level module, not a local module. That's it! If you like, you can think of a import X statement as a combination of import qualified X and import module X statement: the first loads the external compilation unit named X (in a file X.hs) and brings lots of X.blah entities into scope, and the second removes the X. qualification.
Another way to think about this is that there is really no distinction between top-level modules and local modules, but there is a distinction between a compilation unit and a module. An import statement names a compilation unit, granting access to any modules it contains. Haskell separately has two restrictions:
Every compilation unit must contain exactly one module (which may contain other modules); the compilation unit must have the same name as its one module. import statements must go before all other statements (except, optionally, for a module header) in a compilation unit (in order to support finding dependencies while parsing only a prefix of a file). I hope this helps! Richard
On Jul 23, 2021, at 7:16 AM, Alejandro Serrano Mena
wrote: Re-reading the thread has made me aware of the distinction introduced by this proposal between “top-level” and “local modules”, which I do not fully grasp. I was under the impression that this was working more on the syntactic level (so if I write `module X where module Y where` this is similar to `module X.Y where`), and the specification was about sorting out how this works, but now I’m surprised about this new concept.
Regards, Alejandro
El 23 jul 2021 12:00:40, Simon Marlow
mailto:marlowsd@gmail.com> escribió: Just so I'm not completely silent: in the past I was generally in favour but had some suggestions. It looks like the proposal has undergone a lot of rewrites since I last reviewed it (or perhaps I just don't remember it all that well), I've started to go through it again but this is a biggie! I think a deadline is a good idea.
Cheers Simon
On Fri, 23 Jul 2021 at 07:23, Spiwack, Arnaud
mailto:arnaud.spiwack@tweag.io> wrote: Dear all, I know that this proposal is a bit long, but it also deserves your attention.
I feel it's going to be easier to set a bit of time to review the proposal if I give a deadline. So let's say the following: I'll be on holiday starting two weeks from now (6th August), can I have everybody's opinion by then?
---
Recapitulating the opinions so far I'm personally pretty enthusiastic about the entire proposal Tom voiced quite enthusiastic support for what Simon PJ calls (1), and (3) Simon PJ wants (1), is not against (2), is mildly against (3) Joachim suspends his judgement (which is fine, but hopefully not too many of us do this :-) ).
On Wed, Jul 21, 2021 at 2:30 PM Simon Peyton Jones
mailto:simonpj@microsoft.com> wrote: To be clear, I’m ok with (1), luke-warm on (2), and mildly against (3) Import and export of qualified names. This seems like the Main Point. Local import (in a let/where). This seems low pain but low gain. Local modules. This is the one I'm struggling with. There is more on the (tail end of the) PR https://github.com/ghc-proposals/ghc-proposals/pull/283 https://github.com/ghc-proposals/ghc-proposals/pull/283
I am open to being educated.
I would love to hear from other members of the committee. Tom’s thumbs-up seemed to about (1), without saying anything about (2) and (3).
One mechanism (if my categorisation is correct) could be to ask everyone to vote (yes/no/maybe) on all of 1,2,3.
Arnaud, you are our shepherd. Your sheep await your command.
Simon
From: ghc-steering-committee
mailto:ghc-steering-committee-bounces@haskell.org> On Behalf Of Richard Eisenberg Sent: 19 July 2021 21:18 To: Spiwack, Arnaud mailto:arnaud.spiwack@tweag.io> Cc: GHC Steering Committee mailto:ghc-steering-committee@haskell.org> Subject: Re: [ghc-steering-committee] #283: Local modules (again), recommendation: accept Any thoughts on this? Simon PJ seems lukewarm (or maybe even cooler than that), Arnaud is in support, but the rest of you have been quiet.
Thanks!
Richard
On Jun 11, 2021, at 3:05 AM, Spiwack, Arnaud
mailto:arnaud.spiwack@tweag.io> wrote: Dear all,
Let me raise this proposal again. Very few of us have opined, and while I'd usually be happy to consider silence as assent, this is a rather large proposal which may require a few more pairs of eyes. Please consider giving this one a read and share your thoughts. If you can't do so right now, please let me know when you will be able to, so that we can plan accordingly.
This is an important proposal, I'm keen on seeing its design finalised.
/Arnaud
On Wed, May 26, 2021 at 2:35 PM Richard Eisenberg
mailto:rae@richarde.dev> wrote: On May 26, 2021, at 3:28 AM, Spiwack, Arnaud
mailto:arnaud.spiwack@tweag.io> wrote: I'm realising that I inverted additional options 1 and 3 in my reply. To spell things out: I'm in favour of the namespace introduced for every datatype and such; and weakly in favour of anonymous modules, for which I prefer the `_` syntax than simply omitting the name.
Oh, good. I was very confused here, but I decided not to push on it. I'm similarly weakly in favor of (1), but I can't get myself to decide firmly on whether to go with alternative (7). Going with (7) is a little more consistent with other features, but it adds more symbols to the source text that could otherwise be omitted. So I'm pretty ambivalent.
Richard
On Tue, May 25, 2021 at 11:54 PM Richard Eisenberg
mailto:rae@richarde.dev> wrote: On May 25, 2021, at 3:09 PM, Alejandro Serrano Mena
mailto:trupill@gmail.com> wrote: - I am not sure of the benefit of allowing (1), compared with the possible surprise of users.
- I do not fully understand (2).
- I think (3) would be great, if we ensure that nothing changes if I don’t use “qualified”, even if -XLocalModules is on.
If in the language, I would use (1) -- anonymous local modules -- regularly, when defining a function or class instance with a bunch of "local" helper functions. Of course, if we can't omit the module name, I will suffer no great harm.
I cannot offer the guarantee you seek in (3), but I don't think you want it. (If nothing changes, then the feature has no effect!) Here is a scenario where (3) could cause trouble:
import Data.Set as Set ( abcde )
data Set = Mk { abcdf :: Int }
blah = Set.abcdf
Previously, GHC would have suggested that you perhaps misspelled abcde. Now, you'll get (presumably) a type error.
Here's another case:
import Data.Set as Set ( Set )
data Set = Mk
x :: Set.Set
Everything is happy today, but with -XLocalModules (and (3)), the type of x is an ambiguous name.
Any example that causes trouble, though, will have something in common: an imported module name (possibly via an alias) that matches a locally defined type name. I would imagine this pattern is rare in practice, and that the benefit of (3) would outweigh the number of times that a problem like this bites.
I, too, could live without (2).
Richard
_______________________________________________ ghc-steering-committee mailing list ghc-steering-committee@haskell.org mailto:ghc-steering-committee@haskell.org https://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-steering-committee https://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-steering-committee _______________________________________________ ghc-steering-committee mailing list ghc-steering-committee@haskell.org mailto:ghc-steering-committee@haskell.org https://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-steering-committee https://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-steering-committee

I hope this helps!
Alas it leaves me even more confused.
Now there are three concepts in play
* local module
* top-level module
* compilation unit
I think that perhaps top-level module = compilation unit.
But no, you say "there is really no distinction between top-level modules and local modules, but there is a distinction between a compilation unit and a module".
So you seem to be saying "top-level module = local module". But then you say "An import statement can name only a top-level module, not a local module." suggesting that local modules and top level modules are not the same after all.
I'm sorry, but I'm pretty baffled
Simon
From: ghc-steering-committee

On Jul 26, 2021, at 5:38 PM, Simon Peyton Jones
wrote: I hope this helps!
Alas it leaves me even more confused.
Somehow I knew you'd say that.
Now there are three concepts in play local module top-level module compilation unit I think that perhaps top-level module = compilation unit.
A compilation unit is a chunk of Haskell code which is considered all at once, producing one .o file. Currently, compilation units are coincident both with files on disk and modules. This proposal allows us to have modules smaller than a compilation unit, but Haskell has a restriction that a compilation unit (= file on disk) contains precisely one module (which may contain others), as well as a restriction about where `import` statements appear. This little part, starting with "another way to think about this" is meant to provide intuition, if you're already familiar with compilation units. It is separate from the points above -- and is just meant to guide intuition. (For example, I have not properly defined "compilation unit".) If it does not connect with you, skip. Instead, look at the three differences between top-level modules and local modules a little further up, and see that this distinction is very superficial. Richard
But no, you say “there is really no distinction between top-level modules and local modules, but there is a distinction between a compilation unit and a module”. So you seem to be saying “top-level module = local module”. But then you say “An import statement can name only a top-level module, not a local module.” suggesting that local modules and top level modules are not the same after all. I’m sorry, but I’m pretty baffled Simon
From: ghc-steering-committee
On Behalf Of Richard Eisenberg Sent: 26 July 2021 17:55 To: Alejandro Serrano Mena Cc: GHC Steering Committee Subject: Re: [ghc-steering-committee] #283: Local modules (again), recommendation: accept Hi Alejandro,
This distinction between top-level module and local module is pretty superficial. I've added a new bit to the proposal to explain this:
· This proposal describes top-level modules as distinct from local modules, but this distinction has little import. Here is the full set of differences between these concepts: The module keyword for a top-level module is the first lexeme in a file; the module keyword for a local module must not be the first lexeme in a file. A top-level module can have import statements; a local module can have only import module statements. An import statement can name only a top-level module, not a local module. That's it! If you like, you can think of a import X statement as a combination of import qualified X and import module X statement: the first loads the external compilation unit named X (in a file X.hs) and brings lots of X.blahentities into scope, and the second removes the X. qualification. Another way to think about this is that there is really no distinction between top-level modules and local modules, but there is a distinction between a compilation unit and a module. An import statement names a compilation unit, granting access to any modules it contains. Haskell separately has two restrictions: Every compilation unit must contain exactly one module (which may contain other modules); the compilation unit must have the same name as its one module. import statements must go before all other statements (except, optionally, for a module header) in a compilation unit (in order to support finding dependencies while parsing only a prefix of a file). I hope this helps! Richard
On Jul 23, 2021, at 7:16 AM, Alejandro Serrano Mena
mailto:trupill@gmail.com> wrote: Re-reading the thread has made me aware of the distinction introduced by this proposal between “top-level” and “local modules”, which I do not fully grasp. I was under the impression that this was working more on the syntactic level (so if I write `module X where module Y where` this is similar to `module X.Y where`), and the specification was about sorting out how this works, but now I’m surprised about this new concept.
Regards, Alejandro
El 23 jul 2021 12:00:40, Simon Marlow
mailto:marlowsd@gmail.com> escribió: Just so I'm not completely silent: in the past I was generally in favour but had some suggestions. It looks like the proposal has undergone a lot of rewrites since I last reviewed it (or perhaps I just don't remember it all that well), I've started to go through it again but this is a biggie! I think a deadline is a good idea.
Cheers Simon
On Fri, 23 Jul 2021 at 07:23, Spiwack, Arnaud
mailto:arnaud.spiwack@tweag.io> wrote: Dear all, I know that this proposal is a bit long, but it also deserves your attention.
I feel it's going to be easier to set a bit of time to review the proposal if I give a deadline. So let's say the following: I'll be on holiday starting two weeks from now (6th August), can I have everybody's opinion by then?
---
Recapitulating the opinions so far I'm personally pretty enthusiastic about the entire proposal Tom voiced quite enthusiastic support for what Simon PJ calls (1), and (3) Simon PJ wants (1), is not against (2), is mildly against (3) Joachim suspends his judgement (which is fine, but hopefully not too many of us do this :-) ).
On Wed, Jul 21, 2021 at 2:30 PM Simon Peyton Jones
mailto:simonpj@microsoft.com> wrote: To be clear, I’m ok with (1), luke-warm on (2), and mildly against (3) Import and export of qualified names. This seems like the Main Point. Local import (in a let/where). This seems low pain but low gain. Local modules. This is the one I'm struggling with. There is more on the (tail end of the) PR https://github.com/ghc-proposals/ghc-proposals/pull/283 https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fghc-proposals%2Fghc-proposals%2Fpull%2F283&data=04%7C01%7Csimonpj%40microsoft.com%7C46ab11d6561e40b7dfb608d9505636f2%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637629154431063086%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000&sdata=IL2LIK2SWo9Idqrip5I1IQy9pvt02v0tfP9pDmIPV5w%3D&reserved=0 I am open to being educated.
I would love to hear from other members of the committee. Tom’s thumbs-up seemed to about (1), without saying anything about (2) and (3).
One mechanism (if my categorisation is correct) could be to ask everyone to vote (yes/no/maybe) on all of 1,2,3.
Arnaud, you are our shepherd. Your sheep await your command.
Simon
From: ghc-steering-committee
mailto:ghc-steering-committee-bounces@haskell.org> On Behalf Of Richard Eisenberg Sent: 19 July 2021 21:18 To: Spiwack, Arnaud mailto:arnaud.spiwack@tweag.io> Cc: GHC Steering Committee mailto:ghc-steering-committee@haskell.org> Subject: Re: [ghc-steering-committee] #283: Local modules (again), recommendation: accept Any thoughts on this? Simon PJ seems lukewarm (or maybe even cooler than that), Arnaud is in support, but the rest of you have been quiet.
Thanks! Richard
On Jun 11, 2021, at 3:05 AM, Spiwack, Arnaud
mailto:arnaud.spiwack@tweag.io> wrote: Dear all,
Let me raise this proposal again. Very few of us have opined, and while I'd usually be happy to consider silence as assent, this is a rather large proposal which may require a few more pairs of eyes. Please consider giving this one a read and share your thoughts. If you can't do so right now, please let me know when you will be able to, so that we can plan accordingly.
This is an important proposal, I'm keen on seeing its design finalised.
/Arnaud
On Wed, May 26, 2021 at 2:35 PM Richard Eisenberg
mailto:rae@richarde.dev> wrote: On May 26, 2021, at 3:28 AM, Spiwack, Arnaud
mailto:arnaud.spiwack@tweag.io> wrote: I'm realising that I inverted additional options 1 and 3 in my reply. To spell things out: I'm in favour of the namespace introduced for every datatype and such; and weakly in favour of anonymous modules, for which I prefer the `_` syntax than simply omitting the name.
Oh, good. I was very confused here, but I decided not to push on it. I'm similarly weakly in favor of (1), but I can't get myself to decide firmly on whether to go with alternative (7). Going with (7) is a little more consistent with other features, but it adds more symbols to the source text that could otherwise be omitted. So I'm pretty ambivalent.
Richard
On Tue, May 25, 2021 at 11:54 PM Richard Eisenberg
mailto:rae@richarde.dev> wrote: On May 25, 2021, at 3:09 PM, Alejandro Serrano Mena
mailto:trupill@gmail.com> wrote: - I am not sure of the benefit of allowing (1), compared with the possible surprise of users. - I do not fully understand (2). - I think (3) would be great, if we ensure that nothing changes if I don’t use “qualified”, even if -XLocalModules is on.
If in the language, I would use (1) -- anonymous local modules -- regularly, when defining a function or class instance with a bunch of "local" helper functions. Of course, if we can't omit the module name, I will suffer no great harm.
I cannot offer the guarantee you seek in (3), but I don't think you want it. (If nothing changes, then the feature has no effect!) Here is a scenario where (3) could cause trouble:
import Data.Set as Set ( abcde )
data Set = Mk { abcdf :: Int }
blah = Set.abcdf
Previously, GHC would have suggested that you perhaps misspelled abcde. Now, you'll get (presumably) a type error.
Here's another case:
import Data.Set as Set ( Set )
data Set = Mk
x :: Set.Set
Everything is happy today, but with -XLocalModules (and (3)), the type of x is an ambiguous name.
Any example that causes trouble, though, will have something in common: an imported module name (possibly via an alias) that matches a locally defined type name. I would imagine this pattern is rare in practice, and that the benefit of (3) would outweigh the number of times that a problem like this bites.
I, too, could live without (2).
Richard
_______________________________________________ ghc-steering-committee mailing list ghc-steering-committee@haskell.org mailto:ghc-steering-committee@haskell.org https://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-steering-committee https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fmail.haskell.org%2Fcgi-bin%2Fmailman%2Flistinfo%2Fghc-steering-committee&data=04%7C01%7Csimonpj%40microsoft.com%7C46ab11d6561e40b7dfb608d9505636f2%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637629154431073081%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000&sdata=7j7afOKKTr63mDs95flG53ii7eo6QSjSFyRdOvp1MUU%3D&reserved=0 _______________________________________________ ghc-steering-committee mailing list ghc-steering-committee@haskell.org mailto:ghc-steering-committee@haskell.org https://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-steering-committee https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fmail.haskell.org%2Fcgi-bin%2Fmailman%2Flistinfo%2Fghc-steering-committee&data=04%7C01%7Csimonpj%40microsoft.com%7C46ab11d6561e40b7dfb608d9505636f2%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637629154431083081%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C3000&sdata=bOtq6xjhCSuB8aPjr4K2lftRJIRtpGOQ9wyLY%2Fhn1q8%3D&reserved=0

OK I finished reading it again. Overall I like it because it's just name
resolution; this is entirely in keeping with Haskell as it stands, and
limits the interaction with current and future language features. As a
smooth extension of the language I think it works nicely.
I rather like the idea of "data qualified" and "class qualified", perhaps
because similar ideas work out quite well in other languages (e.g. C++).
Just one thing concerns me. I don't think this is necessarily a blocker,
but it makes me vaguely uneasy.
Currently, if I see an identifier "M.x", I can search for "M" and be sure
to find it in the import list somewhere, either as "import M" or "import X
as M". I suspect a lot of people rely on this, and some coding styles
strongly encourage the use of qualified names for this reason. Exporting
qualified names and unfortunately breaks this property - any import can
bring into scope qualified names.
The property could be recovered by requiring the explicit import of
qualified names (import Data.Set (module Set, ..) or something like that)
but that doesn't seem very appealing either. Curious whether other people
are worried about this and/or have any suggestions.
Cheers
Simon
On Fri, 23 Jul 2021 at 11:00, Simon Marlow
Just so I'm not completely silent: in the past I was generally in favour but had some suggestions. It looks like the proposal has undergone a lot of rewrites since I last reviewed it (or perhaps I just don't remember it all that well), I've started to go through it again but this is a biggie!
I think a deadline is a good idea.
Cheers Simon
On Fri, 23 Jul 2021 at 07:23, Spiwack, Arnaud
wrote: Dear all,
I know that this proposal is a bit long, but it also deserves your attention.
I feel it's going to be easier to set a bit of time to review the proposal if I give a deadline. So let's say the following: I'll be on holiday starting two weeks from now (6th August), can I have everybody's opinion by then?
---
Recapitulating the opinions so far
- I'm personally pretty enthusiastic about the entire proposal - Tom voiced quite enthusiastic support for what Simon PJ calls (1), and (3) - Simon PJ wants (1), is not against (2), is mildly against (3) - Joachim suspends his judgement (which is fine, but hopefully not too many of us do this :-) ).
On Wed, Jul 21, 2021 at 2:30 PM Simon Peyton Jones
wrote: To be clear, I’m ok with (1), luke-warm on (2), and mildly against (3)
1. Import and export of qualified names. This seems like the Main Point. 2. Local import (in a let/where). This seems low pain but low gain. 3. Local modules. This is the one I'm struggling with.
There is more on the (tail end of the) PR https://github.com/ghc-proposals/ghc-proposals/pull/283
I am open to being educated.
I would love to hear from other members of the committee. Tom’s thumbs-up seemed to about (1), without saying anything about (2) and (3).
One mechanism (if my categorisation is correct) could be to ask everyone to vote (yes/no/maybe) on all of 1,2,3.
Arnaud, you are our shepherd. Your sheep await your command.
Simon
*From:* ghc-steering-committee < ghc-steering-committee-bounces@haskell.org> *On Behalf Of *Richard Eisenberg *Sent:* 19 July 2021 21:18 *To:* Spiwack, Arnaud
*Cc:* GHC Steering Committee *Subject:* Re: [ghc-steering-committee] #283: Local modules (again), recommendation: accept Any thoughts on this? Simon PJ seems lukewarm (or maybe even cooler than that), Arnaud is in support, but the rest of you have been quiet.
Thanks!
Richard
On Jun 11, 2021, at 3:05 AM, Spiwack, Arnaud
wrote: Dear all,
Let me raise this proposal again. Very few of us have opined, and while I'd usually be happy to consider silence as assent, this is a rather large proposal which may require a few more pairs of eyes. Please consider giving this one a read and share your thoughts. If you can't do so right now, please let me know when you will be able to, so that we can plan accordingly.
This is an important proposal, I'm keen on seeing its design finalised.
/Arnaud
On Wed, May 26, 2021 at 2:35 PM Richard Eisenberg
wrote: On May 26, 2021, at 3:28 AM, Spiwack, Arnaud
wrote: I'm realising that I inverted additional options 1 and 3 in my reply. To spell things out: I'm in favour of the namespace introduced for every datatype and such; and weakly in favour of anonymous modules, for which I prefer the `_` syntax than simply omitting the name.
Oh, good. I was very confused here, but I decided not to push on it. I'm similarly weakly in favor of (1), but I can't get myself to decide firmly on whether to go with alternative (7). Going with (7) is a little more consistent with other features, but it adds more symbols to the source text that could otherwise be omitted. So I'm pretty ambivalent.
Richard
On Tue, May 25, 2021 at 11:54 PM Richard Eisenberg
wrote: On May 25, 2021, at 3:09 PM, Alejandro Serrano Mena
wrote: - I am not sure of the benefit of allowing (1), compared with the possible surprise of users.
- I do not fully understand (2).
- I think (3) would be great, if we ensure that nothing changes if I don’t use “qualified”, even if -XLocalModules is on.
If in the language, I would use (1) -- anonymous local modules -- regularly, when defining a function or class instance with a bunch of "local" helper functions. Of course, if we can't omit the module name, I will suffer no great harm.
I cannot offer the guarantee you seek in (3), but I don't think you want it. (If nothing changes, then the feature has no effect!) Here is a scenario where (3) could cause trouble:
import Data.Set as Set ( abcde )
data Set = Mk { abcdf :: Int }
blah = Set.abcdf
Previously, GHC would have suggested that you perhaps misspelled abcde. Now, you'll get (presumably) a type error.
Here's another case:
import Data.Set as Set ( Set )
data Set = Mk
x :: Set.Set
Everything is happy today, but with -XLocalModules (and (3)), the type of x is an ambiguous name.
Any example that causes trouble, though, will have something in common: an imported module name (possibly via an alias) that matches a locally defined type name. I would imagine this pattern is rare in practice, and that the benefit of (3) would outweigh the number of times that a problem like this bites.
I, too, could live without (2).
Richard
_______________________________________________ ghc-steering-committee mailing list ghc-steering-committee@haskell.org https://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-steering-committee

On Jul 24, 2021, at 7:47 AM, Simon Marlow
wrote: OK I finished reading it again. Overall I like it because it's just name resolution; this is entirely in keeping with Haskell as it stands, and limits the interaction with current and future language features. As a smooth extension of the language I think it works nicely.
I rather like the idea of "data qualified" and "class qualified", perhaps because similar ideas work out quite well in other languages (e.g. C++).
Just one thing concerns me. I don't think this is necessarily a blocker, but it makes me vaguely uneasy.
Currently, if I see an identifier "M.x", I can search for "M" and be sure to find it in the import list somewhere, either as "import M" or "import X as M". I suspect a lot of people rely on this, and some coding styles strongly encourage the use of qualified names for this reason. Exporting qualified names and unfortunately breaks this property - any import can bring into scope qualified names.
The property could be recovered by requiring the explicit import of qualified names (import Data.Set (module Set, ..) or something like that) but that doesn't seem very appealing either. Curious whether other people are worried about this and/or have any suggestions.
This is true -- but it's simply a problem of unqualified imports. I can always have `import qualified Data.Set as S` and then use `S.Set`. The problem would be if `Data.Set` exports qualified names like `Set.fromList`. Now, if `Data.Set` is itself imported qualified, we have `S.Set.fromList`, which is unfortunate. One idea could be a new import item `import module M impspec` which behaves just like `module M impspec`, but without the use of `qualify` in its interpretation. In code:
interpretImpItem('import' 'module' modids impspec, export_env) = interpretImpSpec(impspec, strip(modids, export_env)) interpretImpItem('import' 'module' modids, export_env) = strip(modids, export_env)
Now, we could say
import qualified Data.Set ( import module Set ) as S
which would bring e.g. `S.Set` and `S.fromList` into scope. This new `import module` import item would enable this idiom. (This is all possible with the proposal as stated, but not nearly as easily.) Would that help? Then, someone who cared about the property you want would be able to suggest a coding style that would maintain it. Richard
Cheers Simon
On Fri, 23 Jul 2021 at 11:00, Simon Marlow
mailto:marlowsd@gmail.com> wrote: Just so I'm not completely silent: in the past I was generally in favour but had some suggestions. It looks like the proposal has undergone a lot of rewrites since I last reviewed it (or perhaps I just don't remember it all that well), I've started to go through it again but this is a biggie! I think a deadline is a good idea.
Cheers Simon
On Fri, 23 Jul 2021 at 07:23, Spiwack, Arnaud
mailto:arnaud.spiwack@tweag.io> wrote: Dear all, I know that this proposal is a bit long, but it also deserves your attention.
I feel it's going to be easier to set a bit of time to review the proposal if I give a deadline. So let's say the following: I'll be on holiday starting two weeks from now (6th August), can I have everybody's opinion by then?
---
Recapitulating the opinions so far I'm personally pretty enthusiastic about the entire proposal Tom voiced quite enthusiastic support for what Simon PJ calls (1), and (3) Simon PJ wants (1), is not against (2), is mildly against (3) Joachim suspends his judgement (which is fine, but hopefully not too many of us do this :-) ).
On Wed, Jul 21, 2021 at 2:30 PM Simon Peyton Jones
mailto:simonpj@microsoft.com> wrote: To be clear, I’m ok with (1), luke-warm on (2), and mildly against (3) Import and export of qualified names. This seems like the Main Point. Local import (in a let/where). This seems low pain but low gain. Local modules. This is the one I'm struggling with. There is more on the (tail end of the) PR https://github.com/ghc-proposals/ghc-proposals/pull/283 https://github.com/ghc-proposals/ghc-proposals/pull/283
I am open to being educated.
I would love to hear from other members of the committee. Tom’s thumbs-up seemed to about (1), without saying anything about (2) and (3).
One mechanism (if my categorisation is correct) could be to ask everyone to vote (yes/no/maybe) on all of 1,2,3.
Arnaud, you are our shepherd. Your sheep await your command.
Simon
From: ghc-steering-committee
mailto:ghc-steering-committee-bounces@haskell.org> On Behalf Of Richard Eisenberg Sent: 19 July 2021 21:18 To: Spiwack, Arnaud mailto:arnaud.spiwack@tweag.io> Cc: GHC Steering Committee mailto:ghc-steering-committee@haskell.org> Subject: Re: [ghc-steering-committee] #283: Local modules (again), recommendation: accept Any thoughts on this? Simon PJ seems lukewarm (or maybe even cooler than that), Arnaud is in support, but the rest of you have been quiet.
Thanks!
Richard
On Jun 11, 2021, at 3:05 AM, Spiwack, Arnaud
mailto:arnaud.spiwack@tweag.io> wrote: Dear all,
Let me raise this proposal again. Very few of us have opined, and while I'd usually be happy to consider silence as assent, this is a rather large proposal which may require a few more pairs of eyes. Please consider giving this one a read and share your thoughts. If you can't do so right now, please let me know when you will be able to, so that we can plan accordingly.
This is an important proposal, I'm keen on seeing its design finalised.
/Arnaud
On Wed, May 26, 2021 at 2:35 PM Richard Eisenberg
mailto:rae@richarde.dev> wrote: On May 26, 2021, at 3:28 AM, Spiwack, Arnaud
mailto:arnaud.spiwack@tweag.io> wrote: I'm realising that I inverted additional options 1 and 3 in my reply. To spell things out: I'm in favour of the namespace introduced for every datatype and such; and weakly in favour of anonymous modules, for which I prefer the `_` syntax than simply omitting the name.
Oh, good. I was very confused here, but I decided not to push on it. I'm similarly weakly in favor of (1), but I can't get myself to decide firmly on whether to go with alternative (7). Going with (7) is a little more consistent with other features, but it adds more symbols to the source text that could otherwise be omitted. So I'm pretty ambivalent.
Richard
On Tue, May 25, 2021 at 11:54 PM Richard Eisenberg
mailto:rae@richarde.dev> wrote: On May 25, 2021, at 3:09 PM, Alejandro Serrano Mena
mailto:trupill@gmail.com> wrote: - I am not sure of the benefit of allowing (1), compared with the possible surprise of users.
- I do not fully understand (2).
- I think (3) would be great, if we ensure that nothing changes if I don’t use “qualified”, even if -XLocalModules is on.
If in the language, I would use (1) -- anonymous local modules -- regularly, when defining a function or class instance with a bunch of "local" helper functions. Of course, if we can't omit the module name, I will suffer no great harm.
I cannot offer the guarantee you seek in (3), but I don't think you want it. (If nothing changes, then the feature has no effect!) Here is a scenario where (3) could cause trouble:
import Data.Set as Set ( abcde )
data Set = Mk { abcdf :: Int }
blah = Set.abcdf
Previously, GHC would have suggested that you perhaps misspelled abcde. Now, you'll get (presumably) a type error.
Here's another case:
import Data.Set as Set ( Set )
data Set = Mk
x :: Set.Set
Everything is happy today, but with -XLocalModules (and (3)), the type of x is an ambiguous name.
Any example that causes trouble, though, will have something in common: an imported module name (possibly via an alias) that matches a locally defined type name. I would imagine this pattern is rare in practice, and that the benefit of (3) would outweigh the number of times that a problem like this bites.
I, too, could live without (2).
Richard
_______________________________________________ ghc-steering-committee mailing list ghc-steering-committee@haskell.org mailto:ghc-steering-committee@haskell.org https://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-steering-committee https://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-steering-committee

One idea could be a new import item `import module M impspec` which behaves just like `module M impspec`, but without the use of `qualify` in its interpretation. In code:
Not so great in cases where
import Graphics
imports Button.open and Widget.open
If you qualify, thus
import Graphics as G
then you want G.Button.open and G.Widget.open. You really don't want to strip off the carefully added Button and Widget qualifiers.
To be more explicit, I guess you could say
import Graphics( Buttton.*, Widget.* )
or perhaps more Haskell-y
import Graphics( module Button, module Widget )
and indeed I believe the proposal supports precisely that.
Currently, if I see an identifier "M.x", I can search for "M" and be sure to find it in the import list somewhere, either as "import M" or "import X as M".
Yes, that's convenient. But it would also be convenient if, which I see an identifier "x", I could always see where it is imported from. But sadly I can't - and I often find myself guessing. So it's not a new shortcoming of this proposal.
One could imagine a new flag, ExplicitBinders, whose principle is that it is easy to determine from every occurrence which import(s) brings it into scope. For an unqualified "x" that would mean you'd have to
* either import "x" explicitly, import M(x)
* or change the occurrence to a qualified M.x
That might be a good software engineering practice to follow. Then you could extend the same treatment to this new proposal.
Simon
From: Richard Eisenberg
import qualified Data.Set ( import module Set ) as S
which would bring e.g. `S.Set` and `S.fromList` into scope.
This new `import module` import item would enable this idiom. (This is all possible with the proposal as stated, but not nearly as easily.) Would that help? Then, someone who cared about the property you want would be able to suggest a coding style that would maintain it.
Richard
Cheers
Simon
On Fri, 23 Jul 2021 at 11:00, Simon Marlow

On Mon, 26 Jul 2021 at 18:08, Richard Eisenberg
One idea could be a new import item `import module M impspec` which behaves just like `module M impspec`, but without the use of `qualify` in its interpretation. In code:
interpretImpItem('import' 'module' modids impspec, export_env) = interpretImpSpec(impspec, strip(modids, export_env)) interpretImpItem('import' 'module' modids, export_env) = strip(modids, export_env)
Now, we could say
import qualified Data.Set ( import module Set ) as S
which would bring e.g. `S.Set` and `S.fromList` into scope.
This new `import module` import item would enable this idiom. (This is all possible with the proposal as stated, but not nearly as easily.) Would that help? Then, someone who cared about the property you want would be able to suggest a coding style that would maintain it.
As you say, you can do this using the proposal as is: module qualified S (module Set) where import Data.Set so I don't think it's worth adding anything new, given that this is already quite brief. (if perhaps a little obscure, but you could imagine getting used to it) But while thinking about this I realised I'm more concerned that we would have two kinds of qualification that behave in quite different ways, yet look identical. One is top-level modules, which you can bring into scoe and rename with import declarations, and the other is qualified exports which are controlled with export and import specifiers. When I refer to an identifier like A.B.C.x, zero or more of the modids come from the import declaration. This is powerful, yes, but also potentially a source of great confusion. I find it hard to predict exactly how this will work out in practice. Cheers Simon
Richard
Cheers Simon
On Fri, 23 Jul 2021 at 11:00, Simon Marlow
wrote: Just so I'm not completely silent: in the past I was generally in favour but had some suggestions. It looks like the proposal has undergone a lot of rewrites since I last reviewed it (or perhaps I just don't remember it all that well), I've started to go through it again but this is a biggie!
I think a deadline is a good idea.
Cheers Simon
On Fri, 23 Jul 2021 at 07:23, Spiwack, Arnaud
wrote: Dear all,
I know that this proposal is a bit long, but it also deserves your attention.
I feel it's going to be easier to set a bit of time to review the proposal if I give a deadline. So let's say the following: I'll be on holiday starting two weeks from now (6th August), can I have everybody's opinion by then?
---
Recapitulating the opinions so far
- I'm personally pretty enthusiastic about the entire proposal - Tom voiced quite enthusiastic support for what Simon PJ calls (1), and (3) - Simon PJ wants (1), is not against (2), is mildly against (3) - Joachim suspends his judgement (which is fine, but hopefully not too many of us do this :-) ).
On Wed, Jul 21, 2021 at 2:30 PM Simon Peyton Jones < simonpj@microsoft.com> wrote:
To be clear, I’m ok with (1), luke-warm on (2), and mildly against (3)
1. Import and export of qualified names. This seems like the Main Point. 2. Local import (in a let/where). This seems low pain but low gain. 3. Local modules. This is the one I'm struggling with.
There is more on the (tail end of the) PR https://github.com/ghc-proposals/ghc-proposals/pull/283
I am open to being educated.
I would love to hear from other members of the committee. Tom’s thumbs-up seemed to about (1), without saying anything about (2) and (3).
One mechanism (if my categorisation is correct) could be to ask everyone to vote (yes/no/maybe) on all of 1,2,3.
Arnaud, you are our shepherd. Your sheep await your command.
Simon
*From:* ghc-steering-committee < ghc-steering-committee-bounces@haskell.org> *On Behalf Of *Richard Eisenberg *Sent:* 19 July 2021 21:18 *To:* Spiwack, Arnaud
*Cc:* GHC Steering Committee *Subject:* Re: [ghc-steering-committee] #283: Local modules (again), recommendation: accept Any thoughts on this? Simon PJ seems lukewarm (or maybe even cooler than that), Arnaud is in support, but the rest of you have been quiet.
Thanks!
Richard
On Jun 11, 2021, at 3:05 AM, Spiwack, Arnaud
wrote: Dear all,
Let me raise this proposal again. Very few of us have opined, and while I'd usually be happy to consider silence as assent, this is a rather large proposal which may require a few more pairs of eyes. Please consider giving this one a read and share your thoughts. If you can't do so right now, please let me know when you will be able to, so that we can plan accordingly.
This is an important proposal, I'm keen on seeing its design finalised.
/Arnaud
On Wed, May 26, 2021 at 2:35 PM Richard Eisenberg
wrote: On May 26, 2021, at 3:28 AM, Spiwack, Arnaud
wrote: I'm realising that I inverted additional options 1 and 3 in my reply. To spell things out: I'm in favour of the namespace introduced for every datatype and such; and weakly in favour of anonymous modules, for which I prefer the `_` syntax than simply omitting the name.
Oh, good. I was very confused here, but I decided not to push on it. I'm similarly weakly in favor of (1), but I can't get myself to decide firmly on whether to go with alternative (7). Going with (7) is a little more consistent with other features, but it adds more symbols to the source text that could otherwise be omitted. So I'm pretty ambivalent.
Richard
On Tue, May 25, 2021 at 11:54 PM Richard Eisenberg
wrote: On May 25, 2021, at 3:09 PM, Alejandro Serrano Mena
wrote: - I am not sure of the benefit of allowing (1), compared with the possible surprise of users.
- I do not fully understand (2).
- I think (3) would be great, if we ensure that nothing changes if I don’t use “qualified”, even if -XLocalModules is on.
If in the language, I would use (1) -- anonymous local modules -- regularly, when defining a function or class instance with a bunch of "local" helper functions. Of course, if we can't omit the module name, I will suffer no great harm.
I cannot offer the guarantee you seek in (3), but I don't think you want it. (If nothing changes, then the feature has no effect!) Here is a scenario where (3) could cause trouble:
import Data.Set as Set ( abcde )
data Set = Mk { abcdf :: Int }
blah = Set.abcdf
Previously, GHC would have suggested that you perhaps misspelled abcde. Now, you'll get (presumably) a type error.
Here's another case:
import Data.Set as Set ( Set )
data Set = Mk
x :: Set.Set
Everything is happy today, but with -XLocalModules (and (3)), the type of x is an ambiguous name.
Any example that causes trouble, though, will have something in common: an imported module name (possibly via an alias) that matches a locally defined type name. I would imagine this pattern is rare in practice, and that the benefit of (3) would outweigh the number of times that a problem like this bites.
I, too, could live without (2).
Richard
_______________________________________________ ghc-steering-committee mailing list ghc-steering-committee@haskell.org https://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-steering-committee

Dear all,
First sorry I'm a bit late on this, life got in the way.
I've got opinions from both Simons, Tom, and Alejandro. Eric, Joachim,
Vitaly, Vlad what do you think about all this?
---
If I were to summarise the discussion as I understand it, the major point
of discussion is the difference between local modules (which are pure
name-spacing entities) and global/top-level modules (which are compilation
units, hence can appear in import statements for dependency management).
Simon PJ has argued (in an off-band conversation with Richard and I) to
embrace the difference more, though in many places in the proposal, these
two kind of modules are used the same way, hence deserving the common name
of “module”. Simon Marlow is worried that the lack of distinction between
global module addressing and local module addressing in `A.B.C.x` can be
confusing (is `A.B` a global module, or is `A` the global module and `B.C`
the local module?).
(I'd personally argue, regarding this latter point, that it doesn't matter.
By the time we are able to name `A.B.C.x` in a file, global modules may
have been renamed, so we have changed a name representing a compilation
unit into a namespace, which may or may not be identical. The proposal
don't treat the two situations differently at all)
Another point of discussion which hasn't appeared on this list but has been
raised in the Github thread, is that the current proposal goes to great
length to make exporting `module M` more or less compatible with the
current behaviour giving it a very different semantic to exporting `module
qualified M` (these are currently items 4.iv, 4.v, and 4.vi in the
specification section of the proposal). Note that is not fully backwards
compatible and even with existing module can export more stuff. The
question is whether it is worth trying to match the existing behaviour of
`module M`, or whether a simpler notion which is in line with the behaviour
of `module qualified M` would be preferable.
Over to you :-)
/Arnaud
On Tue, Jul 27, 2021 at 6:01 PM Simon Marlow
On Mon, 26 Jul 2021 at 18:08, Richard Eisenberg
wrote: One idea could be a new import item `import module M impspec` which behaves just like `module M impspec`, but without the use of `qualify` in its interpretation. In code:
interpretImpItem('import' 'module' modids impspec, export_env) = interpretImpSpec(impspec, strip(modids, export_env)) interpretImpItem('import' 'module' modids, export_env) = strip(modids, export_env)
Now, we could say
import qualified Data.Set ( import module Set ) as S
which would bring e.g. `S.Set` and `S.fromList` into scope.
This new `import module` import item would enable this idiom. (This is all possible with the proposal as stated, but not nearly as easily.) Would that help? Then, someone who cared about the property you want would be able to suggest a coding style that would maintain it.
As you say, you can do this using the proposal as is:
module qualified S (module Set) where import Data.Set
so I don't think it's worth adding anything new, given that this is already quite brief. (if perhaps a little obscure, but you could imagine getting used to it)
But while thinking about this I realised I'm more concerned that we would have two kinds of qualification that behave in quite different ways, yet look identical. One is top-level modules, which you can bring into scoe and rename with import declarations, and the other is qualified exports which are controlled with export and import specifiers. When I refer to an identifier like A.B.C.x, zero or more of the modids come from the import declaration.
This is powerful, yes, but also potentially a source of great confusion. I find it hard to predict exactly how this will work out in practice.
Cheers Simon
Richard
Cheers Simon
On Fri, 23 Jul 2021 at 11:00, Simon Marlow
wrote: Just so I'm not completely silent: in the past I was generally in favour but had some suggestions. It looks like the proposal has undergone a lot of rewrites since I last reviewed it (or perhaps I just don't remember it all that well), I've started to go through it again but this is a biggie!
I think a deadline is a good idea.
Cheers Simon
On Fri, 23 Jul 2021 at 07:23, Spiwack, Arnaud
wrote: Dear all,
I know that this proposal is a bit long, but it also deserves your attention.
I feel it's going to be easier to set a bit of time to review the proposal if I give a deadline. So let's say the following: I'll be on holiday starting two weeks from now (6th August), can I have everybody's opinion by then?
---
Recapitulating the opinions so far
- I'm personally pretty enthusiastic about the entire proposal - Tom voiced quite enthusiastic support for what Simon PJ calls (1), and (3) - Simon PJ wants (1), is not against (2), is mildly against (3) - Joachim suspends his judgement (which is fine, but hopefully not too many of us do this :-) ).
On Wed, Jul 21, 2021 at 2:30 PM Simon Peyton Jones < simonpj@microsoft.com> wrote:
To be clear, I’m ok with (1), luke-warm on (2), and mildly against (3)
1. Import and export of qualified names. This seems like the Main Point. 2. Local import (in a let/where). This seems low pain but low gain. 3. Local modules. This is the one I'm struggling with.
There is more on the (tail end of the) PR https://github.com/ghc-proposals/ghc-proposals/pull/283
I am open to being educated.
I would love to hear from other members of the committee. Tom’s thumbs-up seemed to about (1), without saying anything about (2) and (3).
One mechanism (if my categorisation is correct) could be to ask everyone to vote (yes/no/maybe) on all of 1,2,3.
Arnaud, you are our shepherd. Your sheep await your command.
Simon
*From:* ghc-steering-committee < ghc-steering-committee-bounces@haskell.org> *On Behalf Of *Richard Eisenberg *Sent:* 19 July 2021 21:18 *To:* Spiwack, Arnaud
*Cc:* GHC Steering Committee *Subject:* Re: [ghc-steering-committee] #283: Local modules (again), recommendation: accept Any thoughts on this? Simon PJ seems lukewarm (or maybe even cooler than that), Arnaud is in support, but the rest of you have been quiet.
Thanks!
Richard
On Jun 11, 2021, at 3:05 AM, Spiwack, Arnaud
wrote: Dear all,
Let me raise this proposal again. Very few of us have opined, and while I'd usually be happy to consider silence as assent, this is a rather large proposal which may require a few more pairs of eyes. Please consider giving this one a read and share your thoughts. If you can't do so right now, please let me know when you will be able to, so that we can plan accordingly.
This is an important proposal, I'm keen on seeing its design finalised.
/Arnaud
On Wed, May 26, 2021 at 2:35 PM Richard Eisenberg
wrote: On May 26, 2021, at 3:28 AM, Spiwack, Arnaud
wrote: I'm realising that I inverted additional options 1 and 3 in my reply. To spell things out: I'm in favour of the namespace introduced for every datatype and such; and weakly in favour of anonymous modules, for which I prefer the `_` syntax than simply omitting the name.
Oh, good. I was very confused here, but I decided not to push on it. I'm similarly weakly in favor of (1), but I can't get myself to decide firmly on whether to go with alternative (7). Going with (7) is a little more consistent with other features, but it adds more symbols to the source text that could otherwise be omitted. So I'm pretty ambivalent.
Richard
On Tue, May 25, 2021 at 11:54 PM Richard Eisenberg
wrote: On May 25, 2021, at 3:09 PM, Alejandro Serrano Mena
wrote: - I am not sure of the benefit of allowing (1), compared with the possible surprise of users.
- I do not fully understand (2).
- I think (3) would be great, if we ensure that nothing changes if I don’t use “qualified”, even if -XLocalModules is on.
If in the language, I would use (1) -- anonymous local modules -- regularly, when defining a function or class instance with a bunch of "local" helper functions. Of course, if we can't omit the module name, I will suffer no great harm.
I cannot offer the guarantee you seek in (3), but I don't think you want it. (If nothing changes, then the feature has no effect!) Here is a scenario where (3) could cause trouble:
import Data.Set as Set ( abcde )
data Set = Mk { abcdf :: Int }
blah = Set.abcdf
Previously, GHC would have suggested that you perhaps misspelled abcde. Now, you'll get (presumably) a type error.
Here's another case:
import Data.Set as Set ( Set )
data Set = Mk
x :: Set.Set
Everything is happy today, but with -XLocalModules (and (3)), the type of x is an ambiguous name.
Any example that causes trouble, though, will have something in common: an imported module name (possibly via an alias) that matches a locally defined type name. I would imagine this pattern is rare in practice, and that the benefit of (3) would outweigh the number of times that a problem like this bites.
I, too, could live without (2).
Richard
_______________________________________________ ghc-steering-committee mailing list ghc-steering-committee@haskell.org https://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-steering-committee

Sorry, I've been meaning to give this one the proper attention it deserves, but have failed to carve out time for it. I will make sure to find time this weekend! On Thu, Oct 7, 2021, at 03:52, Spiwack, Arnaud wrote:
Dear all,
First sorry I'm a bit late on this, life got in the way.
I've got opinions from both Simons, Tom, and Alejandro. Eric, Joachim, Vitaly, Vlad what do you think about all this?
---
If I were to summarise the discussion as I understand it, the major point of discussion is the difference between local modules (which are pure name-spacing entities) and global/top-level modules (which are compilation units, hence can appear in import statements for dependency management). Simon PJ has argued (in an off-band conversation with Richard and I) to embrace the difference more, though in many places in the proposal, these two kind of modules are used the same way, hence deserving the common name of “module”. Simon Marlow is worried that the lack of distinction between global module addressing and local module addressing in `A.B.C.x` can be confusing (is `A.B` a global module, or is `A` the global module and `B.C` the local module?).
(I'd personally argue, regarding this latter point, that it doesn't matter. By the time we are able to name `A.B.C.x` in a file, global modules may have been renamed, so we have changed a name representing a compilation unit into a namespace, which may or may not be identical. The proposal don't treat the two situations differently at all)
Another point of discussion which hasn't appeared on this list but has been raised in the Github thread, is that the current proposal goes to great length to make exporting `module M` more or less compatible with the current behaviour giving it a very different semantic to exporting `module qualified M` (these are currently items 4.iv, 4.v, and 4.vi in the specification section of the proposal). Note that is not fully backwards compatible and even with existing module can export more stuff. The question is whether it is worth trying to match the existing behaviour of `module M`, or whether a simpler notion which is in line with the behaviour of `module qualified M` would be preferable.
Over to you :-)
/Arnaud
On Tue, Jul 27, 2021 at 6:01 PM Simon Marlow
wrote: On Mon, 26 Jul 2021 at 18:08, Richard Eisenberg
wrote: One idea could be a new import item `import module M impspec` which behaves just like `module M impspec`, but without the use of `qualify` in its interpretation. In code:
interpretImpItem('import' 'module' modids impspec, export_env) = interpretImpSpec(impspec, strip(modids, export_env)) interpretImpItem('import' 'module' modids, export_env) = strip(modids, export_env)
Now, we could say
import qualified Data.Set ( import module Set ) as S
which would bring e.g. `S.Set` and `S.fromList` into scope.
This new `import module` import item would enable this idiom. (This is all possible with the proposal as stated, but not nearly as easily.) Would that help? Then, someone who cared about the property you want would be able to suggest a coding style that would maintain it.
As you say, you can do this using the proposal as is:
module qualified S (module Set) where import Data.Set
so I don't think it's worth adding anything new, given that this is already quite brief. (if perhaps a little obscure, but you could imagine getting used to it)
But while thinking about this I realised I'm more concerned that we would have two kinds of qualification that behave in quite different ways, yet look identical. One is top-level modules, which you can bring into scoe and rename with import declarations, and the other is qualified exports which are controlled with export and import specifiers. When I refer to an identifier like A.B.C.x, zero or more of the modids come from the import declaration.
This is powerful, yes, but also potentially a source of great confusion. I find it hard to predict exactly how this will work out in practice.
Cheers Simon
Richard
Cheers Simon
On Fri, 23 Jul 2021 at 11:00, Simon Marlow
wrote: Just so I'm not completely silent: in the past I was generally in favour but had some suggestions. It looks like the proposal has undergone a lot of rewrites since I last reviewed it (or perhaps I just don't remember it all that well), I've started to go through it again but this is a biggie!
I think a deadline is a good idea.
Cheers Simon
On Fri, 23 Jul 2021 at 07:23, Spiwack, Arnaud
wrote: Dear all,
I know that this proposal is a bit long, but it also deserves your attention.
I feel it's going to be easier to set a bit of time to review the proposal if I give a deadline. So let's say the following: I'll be on holiday starting two weeks from now (6th August), can I have everybody's opinion by then?
---
Recapitulating the opinions so far * I'm personally pretty enthusiastic about the entire proposal * Tom voiced quite enthusiastic support for what Simon PJ calls (1), and (3) * Simon PJ wants (1), is not against (2), is mildly against (3) * Joachim suspends his judgement (which is fine, but hopefully not too many of us do this :-) ).
On Wed, Jul 21, 2021 at 2:30 PM Simon Peyton Jones
wrote: > To be clear, I’m ok with (1), luke-warm on (2), and mildly against (3)____ > 1. Import and export of qualified names. This seems like the Main Point.____ > 2. Local import (in a let/where). This seems low pain but low gain.____ > 3. Local modules. This is the one I'm struggling with.____ > There is more on the (tail end of the) PR https://github.com/ghc-proposals/ghc-proposals/pull/283____ > __ __ > I am open to being educated.____ > > I would love to hear from other members of the committee. Tom’s thumbs-up seemed to about (1), without saying anything about (2) and (3).____ > __ __ > One mechanism (if my categorisation is correct) could be to ask everyone to vote (yes/no/maybe) on all of 1,2,3.____ > __ __ > Arnaud, you are our shepherd. Your sheep await your command.____ > __ __ > Simon____ > __ __ > *From:* ghc-steering-committee *On Behalf Of *Richard Eisenberg > *Sent:* 19 July 2021 21:18 > *To:* Spiwack, Arnaud > *Cc:* GHC Steering Committee > *Subject:* Re: [ghc-steering-committee] #283: Local modules (again), recommendation: accept____ > __ __ > Any thoughts on this? Simon PJ seems lukewarm (or maybe even cooler than that), Arnaud is in support, but the rest of you have been quiet.____ > __ __ > Thanks!____ > Richard____ > > > ____ >> On Jun 11, 2021, at 3:05 AM, Spiwack, Arnaud wrote:____ >> __ __ >> Dear all,____ >> __ __ >> Let me raise this proposal again. Very few of us have opined, and while I'd usually be happy to consider silence as assent, this is a rather large proposal which may require a few more pairs of eyes. Please consider giving this one a read and share your thoughts. If you can't do so right now, please let me know when you will be able to, so that we can plan accordingly.____ >> __ __ >> This is an important proposal, I'm keen on seeing its design finalised.____ >> __ __ >> /Arnaud____ >> __ __ >> On Wed, May 26, 2021 at 2:35 PM Richard Eisenberg wrote:____ >>> __ __ >>> >>> >>> ____ >>>> On May 26, 2021, at 3:28 AM, Spiwack, Arnaud wrote:____ >>>> __ __ >>>> I'm realising that I inverted additional options 1 and 3 in my reply. To spell things out: I'm in favour of the namespace introduced for every datatype and such; and weakly in favour of anonymous modules, for which I prefer the `_` syntax than simply omitting the name.____ >>> __ __ >>> Oh, good. I was very confused here, but I decided not to push on it. I'm similarly weakly in favor of (1), but I can't get myself to decide firmly on whether to go with alternative (7). Going with (7) is a little more consistent with other features, but it adds more symbols to the source text that could otherwise be omitted. So I'm pretty ambivalent.____ >>> __ __ >>> Richard____ >>> >>> >>> ____ >>>> __ __ >>>> On Tue, May 25, 2021 at 11:54 PM Richard Eisenberg wrote:____ >>>>> __ __ >>>>> >>>>> >>>>> ____ >>>>>> On May 25, 2021, at 3:09 PM, Alejandro Serrano Mena wrote:____ >>>>>> __ __ >>>>>> - I am not sure of the benefit of allowing (1), compared with the possible surprise of users.____ >>>>>> - I do not fully understand (2).____ >>>>>> - I think (3) would be great, if we ensure that nothing changes if I don’t use “qualified”, even if -XLocalModules is on.____ >>>>> __ __ >>>>> If in the language, I would use (1) -- anonymous local modules -- regularly, when defining a function or class instance with a bunch of "local" helper functions. Of course, if we can't omit the module name, I will suffer no great harm.____ >>>>> __ __ >>>>> I cannot offer the guarantee you seek in (3), but I don't think you want it. (If nothing changes, then the feature has no effect!) Here is a scenario where (3) could cause trouble:____ >>>>> __ __ >>>>>> import Data.Set as Set ( abcde )____ >>>>>> __ __ >>>>>> data Set = Mk { abcdf :: Int }____ >>>>>> __ __ >>>>>> blah = Set.abcdf____ >>>>> __ __ >>>>> Previously, GHC would have suggested that you perhaps misspelled abcde. Now, you'll get (presumably) a type error.____ >>>>> __ __ >>>>> Here's another case:____ >>>>> __ __ >>>>>> import Data.Set as Set ( Set )____ >>>>>> __ __ >>>>>> data Set = Mk____ >>>>>> __ __ >>>>>> x :: Set.Set____ >>>>> __ __ >>>>> Everything is happy today, but with -XLocalModules (and (3)), the type of x is an ambiguous name.____ >>>>> __ __ >>>>> Any example that causes trouble, though, will have something in common: an imported module name (possibly via an alias) that matches a locally defined type name. I would imagine this pattern is rare in practice, and that the benefit of (3) would outweigh the number of times that a problem like this bites.____ >>>>> __ __ >>>>> I, too, could live without (2).____ >>>>> __ __ >>>>> Richard____ >>> __ __ > __ __ _______________________________________________ ghc-steering-committee mailing list ghc-steering-committee@haskell.org https://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-steering-committee
ghc-steering-committee mailing list ghc-steering-committee@haskell.org https://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-steering-committee

I've read through the module and left some technical questions and comments on GitHub. Overall, I'm largely in favor of the proposal, but I think extension 3 (local modules for datatype) is a must. Without it I would be much more ambivalent about the proposal. One concern I have, that I raised on GitHub but will repeat here, is about the implicit export of unqualified names from local modules. It seems truly bizarre to me that we'd accept the following program. ``` module Top where y = x module Inner where x = 5 ``` Am I the only one who finds this strange and counter-intuitive? Eric On Wed, Oct 13, 2021, at 21:05, Eric Seidel wrote:
Sorry, I've been meaning to give this one the proper attention it deserves, but have failed to carve out time for it.
I will make sure to find time this weekend!
On Thu, Oct 7, 2021, at 03:52, Spiwack, Arnaud wrote:
Dear all,
First sorry I'm a bit late on this, life got in the way.
I've got opinions from both Simons, Tom, and Alejandro. Eric, Joachim, Vitaly, Vlad what do you think about all this?
---
If I were to summarise the discussion as I understand it, the major point of discussion is the difference between local modules (which are pure name-spacing entities) and global/top-level modules (which are compilation units, hence can appear in import statements for dependency management). Simon PJ has argued (in an off-band conversation with Richard and I) to embrace the difference more, though in many places in the proposal, these two kind of modules are used the same way, hence deserving the common name of “module”. Simon Marlow is worried that the lack of distinction between global module addressing and local module addressing in `A.B.C.x` can be confusing (is `A.B` a global module, or is `A` the global module and `B.C` the local module?).
(I'd personally argue, regarding this latter point, that it doesn't matter. By the time we are able to name `A.B.C.x` in a file, global modules may have been renamed, so we have changed a name representing a compilation unit into a namespace, which may or may not be identical. The proposal don't treat the two situations differently at all)
Another point of discussion which hasn't appeared on this list but has been raised in the Github thread, is that the current proposal goes to great length to make exporting `module M` more or less compatible with the current behaviour giving it a very different semantic to exporting `module qualified M` (these are currently items 4.iv, 4.v, and 4.vi in the specification section of the proposal). Note that is not fully backwards compatible and even with existing module can export more stuff. The question is whether it is worth trying to match the existing behaviour of `module M`, or whether a simpler notion which is in line with the behaviour of `module qualified M` would be preferable.
Over to you :-)
/Arnaud
On Tue, Jul 27, 2021 at 6:01 PM Simon Marlow
wrote: On Mon, 26 Jul 2021 at 18:08, Richard Eisenberg
wrote: One idea could be a new import item `import module M impspec` which behaves just like `module M impspec`, but without the use of `qualify` in its interpretation. In code:
interpretImpItem('import' 'module' modids impspec, export_env) = interpretImpSpec(impspec, strip(modids, export_env)) interpretImpItem('import' 'module' modids, export_env) = strip(modids, export_env)
Now, we could say
import qualified Data.Set ( import module Set ) as S
which would bring e.g. `S.Set` and `S.fromList` into scope.
This new `import module` import item would enable this idiom. (This is all possible with the proposal as stated, but not nearly as easily.) Would that help? Then, someone who cared about the property you want would be able to suggest a coding style that would maintain it.
As you say, you can do this using the proposal as is:
module qualified S (module Set) where import Data.Set
so I don't think it's worth adding anything new, given that this is already quite brief. (if perhaps a little obscure, but you could imagine getting used to it)
But while thinking about this I realised I'm more concerned that we would have two kinds of qualification that behave in quite different ways, yet look identical. One is top-level modules, which you can bring into scoe and rename with import declarations, and the other is qualified exports which are controlled with export and import specifiers. When I refer to an identifier like A.B.C.x, zero or more of the modids come from the import declaration.
This is powerful, yes, but also potentially a source of great confusion. I find it hard to predict exactly how this will work out in practice.
Cheers Simon
Richard
Cheers Simon
On Fri, 23 Jul 2021 at 11:00, Simon Marlow
wrote: Just so I'm not completely silent: in the past I was generally in favour but had some suggestions. It looks like the proposal has undergone a lot of rewrites since I last reviewed it (or perhaps I just don't remember it all that well), I've started to go through it again but this is a biggie!
I think a deadline is a good idea.
Cheers Simon
On Fri, 23 Jul 2021 at 07:23, Spiwack, Arnaud
wrote: > Dear all, > > I know that this proposal is a bit long, but it also deserves your attention. > > I feel it's going to be easier to set a bit of time to review the proposal if I give a deadline. So let's say the following: I'll be on holiday starting two weeks from now (6th August), can I have everybody's opinion by then? > > --- > > Recapitulating the opinions so far > * I'm personally pretty enthusiastic about the entire proposal > * Tom voiced quite enthusiastic support for what Simon PJ calls (1), and (3) > * Simon PJ wants (1), is not against (2), is mildly against (3) > * Joachim suspends his judgement (which is fine, but hopefully not too many of us do this :-) ). > > On Wed, Jul 21, 2021 at 2:30 PM Simon Peyton Jones wrote: >> To be clear, I’m ok with (1), luke-warm on (2), and mildly against (3)____ >> 1. Import and export of qualified names. This seems like the Main Point.____ >> 2. Local import (in a let/where). This seems low pain but low gain.____ >> 3. Local modules. This is the one I'm struggling with.____ >> There is more on the (tail end of the) PR https://github.com/ghc-proposals/ghc-proposals/pull/283____ >> __ __ >> I am open to being educated.____ >> >> I would love to hear from other members of the committee. Tom’s thumbs-up seemed to about (1), without saying anything about (2) and (3).____ >> __ __ >> One mechanism (if my categorisation is correct) could be to ask everyone to vote (yes/no/maybe) on all of 1,2,3.____ >> __ __ >> Arnaud, you are our shepherd. Your sheep await your command.____ >> __ __ >> Simon____ >> __ __ >> *From:* ghc-steering-committee *On Behalf Of *Richard Eisenberg >> *Sent:* 19 July 2021 21:18 >> *To:* Spiwack, Arnaud >> *Cc:* GHC Steering Committee >> *Subject:* Re: [ghc-steering-committee] #283: Local modules (again), recommendation: accept____ >> __ __ >> Any thoughts on this? Simon PJ seems lukewarm (or maybe even cooler than that), Arnaud is in support, but the rest of you have been quiet.____ >> __ __ >> Thanks!____ >> Richard____ >> >> >> ____ >>> On Jun 11, 2021, at 3:05 AM, Spiwack, Arnaud wrote:____ >>> __ __ >>> Dear all,____ >>> __ __ >>> Let me raise this proposal again. Very few of us have opined, and while I'd usually be happy to consider silence as assent, this is a rather large proposal which may require a few more pairs of eyes. Please consider giving this one a read and share your thoughts. If you can't do so right now, please let me know when you will be able to, so that we can plan accordingly.____ >>> __ __ >>> This is an important proposal, I'm keen on seeing its design finalised.____ >>> __ __ >>> /Arnaud____ >>> __ __ >>> On Wed, May 26, 2021 at 2:35 PM Richard Eisenberg wrote:____ >>>> __ __ >>>> >>>> >>>> ____ >>>>> On May 26, 2021, at 3:28 AM, Spiwack, Arnaud wrote:____ >>>>> __ __ >>>>> I'm realising that I inverted additional options 1 and 3 in my reply. To spell things out: I'm in favour of the namespace introduced for every datatype and such; and weakly in favour of anonymous modules, for which I prefer the `_` syntax than simply omitting the name.____ >>>> __ __ >>>> Oh, good. I was very confused here, but I decided not to push on it. I'm similarly weakly in favor of (1), but I can't get myself to decide firmly on whether to go with alternative (7). Going with (7) is a little more consistent with other features, but it adds more symbols to the source text that could otherwise be omitted. So I'm pretty ambivalent.____ >>>> __ __ >>>> Richard____ >>>> >>>> >>>> ____ >>>>> __ __ >>>>> On Tue, May 25, 2021 at 11:54 PM Richard Eisenberg wrote:____ >>>>>> __ __ >>>>>> >>>>>> >>>>>> ____ >>>>>>> On May 25, 2021, at 3:09 PM, Alejandro Serrano Mena wrote:____ >>>>>>> __ __ >>>>>>> - I am not sure of the benefit of allowing (1), compared with the possible surprise of users.____ >>>>>>> - I do not fully understand (2).____ >>>>>>> - I think (3) would be great, if we ensure that nothing changes if I don’t use “qualified”, even if -XLocalModules is on.____ >>>>>> __ __ >>>>>> If in the language, I would use (1) -- anonymous local modules -- regularly, when defining a function or class instance with a bunch of "local" helper functions. Of course, if we can't omit the module name, I will suffer no great harm.____ >>>>>> __ __ >>>>>> I cannot offer the guarantee you seek in (3), but I don't think you want it. (If nothing changes, then the feature has no effect!) Here is a scenario where (3) could cause trouble:____ >>>>>> __ __ >>>>>>> import Data.Set as Set ( abcde )____ >>>>>>> __ __ >>>>>>> data Set = Mk { abcdf :: Int }____ >>>>>>> __ __ >>>>>>> blah = Set.abcdf____ >>>>>> __ __ >>>>>> Previously, GHC would have suggested that you perhaps misspelled abcde. Now, you'll get (presumably) a type error.____ >>>>>> __ __ >>>>>> Here's another case:____ >>>>>> __ __ >>>>>>> import Data.Set as Set ( Set )____ >>>>>>> __ __ >>>>>>> data Set = Mk____ >>>>>>> __ __ >>>>>>> x :: Set.Set____ >>>>>> __ __ >>>>>> Everything is happy today, but with -XLocalModules (and (3)), the type of x is an ambiguous name.____ >>>>>> __ __ >>>>>> Any example that causes trouble, though, will have something in common: an imported module name (possibly via an alias) that matches a locally defined type name. I would imagine this pattern is rare in practice, and that the benefit of (3) would outweigh the number of times that a problem like this bites.____ >>>>>> __ __ >>>>>> I, too, could live without (2).____ >>>>>> __ __ >>>>>> Richard____ >>>> __ __ >> __ __ > _______________________________________________ > ghc-steering-committee mailing list > ghc-steering-committee@haskell.org > https://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-steering-committee
ghc-steering-committee mailing list ghc-steering-committee@haskell.org https://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-steering-committee

On Sat, Oct 16, 2021, at 14:21, Eric Seidel wrote:
One concern I have, that I raised on GitHub but will repeat here, is about the implicit export of unqualified names from local modules. It seems truly bizarre to me that we'd accept the following program.
``` module Top where y = x module Inner where x = 5 ```
Am I the only one who finds this strange and counter-intuitive?
For those not following GitHub as closely, I think Richard has convinced me that this is the most consistent behavior. https://github.com/ghc-proposals/ghc-proposals/pull/283#discussion_r73029302...
participants (8)
-
Alejandro Serrano Mena
-
Eric Seidel
-
Joachim Breitner
-
Richard Eisenberg
-
Simon Marlow
-
Simon Peyton Jones
-
Spiwack, Arnaud
-
Tom Harding