Proposal: Export String from Data.String (and two related proposals)

Hello, I would like to make three proposals, in order of importance IMHO: 1. Export String from Data.String. Most modules in base and on Hackage of the form: Data.<type> also export <type>. I think it's surprising and confusing that Data.String doesn't conform to this pattern. 2. Unexport String from Data.Char. I feel less strongly about this one, but in general I think it is good that a symbol is exported from as few modules as possible. 3. Export the String operations: lines, words, unlines and unwords from Data.String. I feel even less strongly about this one. However these are operations on Strings so it makes sense to export them from Data.String. As a counter argument you could say these operations either receive or produce a _list_ of Strings so they only belong in Data.List. If we accept 3 then in the spirit of "export a symbol from as few modules as possible", you may expect a fourth proposal: Unexport the String operations: lines, words, unlines and unwords from Data.List. However I think this will break lots of programs. I have no problem also discussing this one though. Discussion deadline: 3 weeks from now: Wednesday 10 November. Ticket with patches: http://hackage.haskell.org/trac/ghc/ticket/4422 Regards, Bas

On 21 October 2010 07:19, Bas van Dijk
Hello,
I would like to make three proposals, in order of importance IMHO:
1. Export String from Data.String. Most modules in base and on Hackage of the form: Data.<type> also export <type>. I think it's surprising and confusing that Data.String doesn't conform to this pattern.
Do you mean have the Prelude re-export String from Data.String or for Data.String to re-export String from the Prelude? -- Ivan Lazar Miljenovic Ivan.Miljenovic@gmail.com IvanMiljenovic.wordpress.com

On Wed, Oct 20, 2010 at 11:42 PM, Ivan Lazar Miljenovic
On 21 October 2010 07:19, Bas van Dijk
wrote: Hello,
I would like to make three proposals, in order of importance IMHO:
1. Export String from Data.String. Most modules in base and on Hackage of the form: Data.<type> also export <type>. I think it's surprising and confusing that Data.String doesn't conform to this pattern.
Do you mean have the Prelude re-export String from Data.String or for Data.String to re-export String from the Prelude?
From the user point of view it doesn't really matter where a symbol is actually defined.
This is how it currently works: module Prelude (...String...) where import GHC.Base (...String...) module Data.Char (...String...) where import GHC.Base (...String...) Proposal 1 is just: module Data.String (...String...) where import GHC.Base (String) Proposal 2 is just unexporting it from Data.Char Proposal 3 is just: module Data.String (...String...,lines, words, unlines, unwords) where import GHC.Base (String) import Data.List (lines, words, unlines, unwords) Bas

On 21 October 2010 09:35, Bas van Dijk
On Wed, Oct 20, 2010 at 11:42 PM, Ivan Lazar Miljenovic
wrote: On 21 October 2010 07:19, Bas van Dijk
wrote: Hello,
I would like to make three proposals, in order of importance IMHO:
1. Export String from Data.String. Most modules in base and on Hackage of the form: Data.<type> also export <type>. I think it's surprising and confusing that Data.String doesn't conform to this pattern.
Do you mean have the Prelude re-export String from Data.String or for Data.String to re-export String from the Prelude?
From the user point of view it doesn't really matter where a symbol is actually defined.
This is how it currently works:
module Prelude (...String...) where import GHC.Base (...String...)
module Data.Char (...String...) where import GHC.Base (...String...)
Proposal 1 is just:
module Data.String (...String...) where import GHC.Base (String)
Proposal 2 is just unexporting it from Data.Char
Proposal 3 is just:
module Data.String (...String...,lines, words, unlines, unwords) where import GHC.Base (String) import Data.List (lines, words, unlines, unwords)
So how would this affect other compilers/interpreters/implementations? Note: I'm tentatively agreeing with at least the first two proposals. -- Ivan Lazar Miljenovic Ivan.Miljenovic@gmail.com IvanMiljenovic.wordpress.com

On Thu, Oct 21, 2010 at 5:08 AM, Ivan Lazar Miljenovic
So how would this affect other compilers/interpreters/implementations?
I just noticed that proposal 2 conflicts with Haskell 2010: http://www.haskell.org/onlinereport/haskell2010/haskellch16.html#x24-2090001... Bas

On Thu, Oct 21, 2010 at 08:45:06AM +0200, Bas van Dijk wrote:
On Thu, Oct 21, 2010 at 5:08 AM, Ivan Lazar Miljenovic
wrote: So how would this affect other compilers/interpreters/implementations?
I just noticed that proposal 2 conflicts with Haskell 2010:
http://www.haskell.org/onlinereport/haskell2010/haskellch16.html#x24-2090001...
I don't think that's a problem. If we agree to change it then H2011 will have the change, and the haskell2010 package has its own copy of the Data.Char module. Thanks Ian

On Wed, Oct 20, 2010 at 10:19 PM, Bas van Dijk
Hello,
I would like to make three proposals, in order of importance IMHO:
1. Export String from Data.String. Most modules in base and on Hackage of the form: Data.<type> also export <type>. I think it's surprising and confusing that Data.String doesn't conform to this pattern.
2. Unexport String from Data.Char. I feel less strongly about this one, but in general I think it is good that a symbol is exported from as few modules as possible.
3. Export the String operations: lines, words, unlines and unwords from Data.String. I feel even less strongly about this one. However these are operations on Strings so it makes sense to export them from Data.String. As a counter argument you could say these operations either receive or produce a _list_ of Strings so they only belong in Data.List.
If we accept 3 then in the spirit of "export a symbol from as few modules as possible", you may expect a fourth proposal: Unexport the String operations: lines, words, unlines and unwords from Data.List. However I think this will break lots of programs. I have no problem also discussing this one though.
Discussion deadline:
3 weeks from now: Wednesday 10 November.
Ticket with patches:
http://hackage.haskell.org/trac/ghc/ticket/4422
Regards,
Bas
The deadline of this proposal has passed. However, due to the recent activity on the libraries list, I would like to extend the deadline by a week: Thursday 18 November. Regarding proposal 2: Unexport String from Data.Char, I made a quick analysis of the latest versions of all packages on Hackage which import String from Data.Char: $ find . -type f -print0 | xargs -0 -e grep -l -e "import.*Data\.Char.*String" ./usb-id-database-0.4.0.4/System/USB/IDDB/Base.hs ./usb-id-database-0.4.0.4/System/USB/IDDB/UsbDotOrg.hs ./usb-id-database-0.4.0.4/System/USB/IDDB/LinuxUsbIdRepo.hs ./usb-id-database-0.4.0.4/System/USB/IDDB/Misc.hs ./ftdi-0.2.0.1/test.hs ./usb-safe-0.11/System/USB/Safe.hs ./safer-file-handles-0.9/System/IO/SaferFileHandles.hs ./ls-usb-0.1.0.7/PrettyDevList.hs ./dstring-0.4/Data/DString.hs ./regional-pointers-0.5/Foreign/C/String/Region.hs ./usb-0.6.0.4/System/USB/Internal.hs ./concurrent-extra-0.6/Control/Concurrent/ReadWriteLock.hs ./concurrent-extra-0.6/TestUtils.hs ./explicit-iomodes-0.6/System/IO/ExplicitIOModes.hs ./hamusic-0.1.2.1/src/Music/Analysis/Abstract2Lilypond.lhs ./hamusic-0.1.2.1/src/Music/Analysis/Base.lhs ./hamusic-0.1.2.1/src/Music/Analysis/Interface.lhs ./musicxml-0.1.2/src/Text/XML/MusicXML/Direction.lhs ./musicxml-0.1.2/src/Text/XML/MusicXML/Common.lhs ./musicxml-0.1.2/src/Text/XML/MusicXML/Note.lhs ./roman-numerals-0.4.0.1/Text/Numeral/Roman.hs All these packages are maintained by either me or my brother, except for hamusic and musicxml which are maintained by Samuel Silva. Regards, Bas

On Wed, 2010-10-20 at 22:19 +0200, Bas van Dijk wrote:
Hello,
I would like to make three proposals, in order of importance IMHO:
1. Export String from Data.String. Most modules in base and on Hackage of the form: Data.<type> also export <type>. I think it's surprising and confusing that Data.String doesn't conform to this pattern.
Seems reasonable.
2. Unexport String from Data.Char. I feel less strongly about this one, but in general I think it is good that a symbol is exported from as few modules as possible.
Again, seems reasonable and you say not too many package break.
3. Export the String operations: lines, words, unlines and unwords from Data.String. I feel even less strongly about this one. However these are operations on Strings so it makes sense to export them from Data.String. As a counter argument you could say these operations either receive or produce a _list_ of Strings so they only belong in Data.List.
I agree. We did this for the ByteString modules, we have Data.ByteString[.Lazy] and Data.ByteString[.Lazy].Char8. Only the latter ones export the functions that depend on the ASCII encoding. These four are the only functions in Data.List that specialise the [a] to [Char].
If we accept 3 then in the spirit of "export a symbol from as few modules as possible", you may expect a fourth proposal: Unexport the String operations: lines, words, unlines and unwords from Data.List. However I think this will break lots of programs. I have no problem also discussing this one though.
Yeah, I agree in principle, but probably best to leave that for later. Duncan

On Wed, Nov 17, 2010 at 9:46 PM, Duncan Coutts
If we accept 3 then in the spirit of "export a symbol from as few modules as possible", you may expect a fourth proposal: Unexport the String operations: lines, words, unlines and unwords from Data.List. However I think this will break lots of programs. I have no problem also discussing this one though.
Yeah, I agree in principle, but probably best to leave that for later.
It obviously needs to go through a deprecation phase. It would be great if we could {-# DEPRECATE #-} an export? So something like: module Data.List ( ... {-# DEPRECATE lines "Exported from Data.String instead" #-} , lines ... ) where ... lines = ... ... Alternatively, we could just {-# DEPRECATE #-} the functions in Data.List and define equivalently named new ones in Data.String. What about doing this for a base-4.3.1 ? Regards, Bas

On Wed, Nov 17, 2010 at 4:06 PM, Bas van Dijk
On Wed, Nov 17, 2010 at 9:46 PM, Duncan Coutts
wrote: If we accept 3 then in the spirit of "export a symbol from as few modules as possible", you may expect a fourth proposal: Unexport the String operations: lines, words, unlines and unwords from Data.List. However I think this will break lots of programs. I have no problem also discussing this one though.
Yeah, I agree in principle, but probably best to leave that for later.
It obviously needs to go through a deprecation phase.
It would be great if we could {-# DEPRECATE #-} an export?
So something like:
module Data.List ( ... {-# DEPRECATE lines "Exported from Data.String instead" #-} , lines ... ) where ... lines = ... ...
Alternatively, we could just {-# DEPRECATE #-} the functions in Data.List and define equivalently named new ones in Data.String.
I thought about this, and I even thought it was a great idea, until I realized that it would be a real bummer for anyone importing both Data.List and Data.String - they would get an error from the compiler unless they specifically hid the functions in question from one of the imports. There is a similar (but perhaps easier to solve?) problem with the deprecated export - the compiler would need to not warn on use of the function if it is imported from multiple sources and at least one of the sources exports it non-deprecated. Antoine

On Wed, Oct 20, 2010 at 10:19 PM, Bas van Dijk
Hello,
I would like to make three proposals, in order of importance IMHO:
1. Export String from Data.String. Most modules in base and on Hackage of the form: Data.<type> also export <type>. I think it's surprising and confusing that Data.String doesn't conform to this pattern.
2. Unexport String from Data.Char. I feel less strongly about this one, but in general I think it is good that a symbol is exported from as few modules as possible.
3. Export the String operations: lines, words, unlines and unwords from Data.String. I feel even less strongly about this one. However these are operations on Strings so it makes sense to export them from Data.String. As a counter argument you could say these operations either receive or produce a _list_ of Strings so they only belong in Data.List.
If we accept 3 then in the spirit of "export a symbol from as few modules as possible", you may expect a fourth proposal: Unexport the String operations: lines, words, unlines and unwords from Data.List. However I think this will break lots of programs. I have no problem also discussing this one though.
Discussion deadline:
3 weeks from now: Wednesday 10 November.
Ticket with patches:
http://hackage.haskell.org/trac/ghc/ticket/4422
Regards,
Bas
I would like to wrap up this proposal. The consensus was that all proposals should be applied: 1. Export String from Data.String. 2. Unexport String from Data.Char. 3. Export the String operations: lines, words, unlines and unwords from Data.String. We leave the 4th proposal for later: Unexport the String operations: lines, words, unlines and unwords from Data.List. I will move the ticket status to 'patch'. Thanks, Bas
participants (5)
-
Antoine Latter
-
Bas van Dijk
-
Duncan Coutts
-
Ian Lynagh
-
Ivan Lazar Miljenovic