Moving basic functions

Hello GHC HQ, hello mailing list, there are a couple of basic functions that I think aren't where they should be. 1. void is currently in Control.Monad. However, it is defined only in terms of fmap (and therefore only has a Functor constraint). Although this function is often used in a monadic setting as ">> return ()", I really don't think Control.Monad is the right place for it. 2. a) swap is the only function from Data.Tuple that is not exported to Prelude. On #haskell, people are sometimes even surprised there /is/ a Data.Tuple, and redefine their own version of swap at need. I therefore suggest including Data.Tuple.swap in the Prelude. The obvious downside of this change would of course be that it breaks code if there is a top-level user-defined version of it. Fixing this is of course trivial, but necessary. b) A related suggestion would be the addition of an irrefutable swap, (swap'?), defined as "swap ~(a,b) = (b,a)", and its addition to Prelude for the same reasons. 3. $>, a flipped version of <$, currently resides in Control.Comonad, but should be in Data.Functor. Applicative has <* and *>, Monad has >>= and =<<, and I personally keep redefining (or specifically importing) $> quite often, and I don't think I'm the only one. As these are quite small changes I think 2 weeks should be a sufficiently long discussion period. Greetings, David

On Wed, 13 Mar 2013, David Luposchainsky wrote:
2. a) swap is the only function from Data.Tuple that is not exported to Prelude. On #haskell, people are sometimes even surprised there /is/ a Data.Tuple, and redefine their own version of swap at need. I therefore suggest including Data.Tuple.swap in the Prelude.
This means that Data.Tuple should contain more functions such that it is used more than today! :-) You may get inspirations from my own Data.Tuple module: http://hackage.haskell.org/packages/archive/utility-ht/0.0.8/doc/html/Data-T...
The obvious downside of this change would of course be that it breaks code if there is a top-level user-defined version of it. Fixing this is of course trivial, but necessary.
Prelude is different from other modules since it is always imported without qualification and without import list. That is, strictly speaking, the Prelude must be in a separate package and you have to import it with tight version bounds like Prelude >98.0.0 && <98.0.1 in order to adhere to the package versioning policy. But actually, Prelude is part of the 'base' package and people tend to specify no version bound at all. Thus it is not only tedious work to update packages to a Prelude that exports 'swap' but it becomes even more tedious to write a package that works with old and new Prelude. - I think it would mean to import all identifiers from Prelude explicitly. For me, importing of Data.Tuple is the smaller problem and the more useful functions it contains the more it pays off.
b) A related suggestion would be the addition of an irrefutable swap, (swap'?), defined as "swap ~(a,b) = (b,a)", and its addition to Prelude for the same reasons.
An alternative to adding a lazy version of every function would be to add a function like forcePair (forcePair ~(a,b) = (a,b)) that can be combined with any pair function.

On Wed, Mar 13, 2013 at 2:58 AM, David Luposchainsky < dluposchainsky@googlemail.com> wrote:
1. void is currently in Control.Monad. However, it is defined only in terms of fmap (and therefore only has a Functor constraint). Although this function is often used in a monadic setting as ">> return ()", I really don't think Control.Monad is the right place for it.
We could reexported the function in both places so we don't have to break code that depends on its current location.
2. a) swap is the only function from Data.Tuple that is not exported to Prelude. On #haskell, people are sometimes even surprised there /is/ a Data.Tuple, and redefine their own version of swap at need. I therefore suggest including Data.Tuple.swap in the Prelude.
The obvious downside of this change would of course be that it breaks code if there is a top-level user-defined version of it. Fixing this is of course trivial, but necessary.
I don't think we should add any more functions to the Prelude. It's a module that's automatically put into scope into every module (unless you explicitly use NoImplicitPrelude). Putting things in a global namespace like that is bad.
b) A related suggestion would be the addition of an irrefutable swap, (swap'?), defined as "swap ~(a,b) = (b,a)", and its addition to Prelude for the same reasons.
Add it to Data.Tuple.
3. $>, a flipped version of <$, currently resides in Control.Comonad, but should be in Data.Functor. Applicative has <* and *>, Monad has >>= and =<<, and I personally keep redefining (or specifically importing) $> quite often, and I don't think I'm the only one.
Makes sense to me.
As these are quite small changes I think 2 weeks should be a sufficiently long discussion period.
Adding things to the Prelude is not a small thing! :) -- Johan

On 2013-03-13 16:39, Johan Tibell wrote:
We could reexported the function [Control.Monad.void] in both places so we don't have to break code that depends on its current location.
That would not only not break code, it would also be a step towards bringing Monad and Functor closer together. If the change is made, I think this is the best way.
Add [irrefutable swap] to Data.Tuple.
Seeing Henning's answer - "better expand libraries than importing outcasts" - I'd be happy with that. It would also make a better case against the "import Data.Tuple is one char less than defining swap yourself" argument: if the module is larger, it makes more (often) sense to import it.
I don't think we should add any more functions to the Prelude. It's a module that's automatically put into scope into every module (unless you explicitly use NoImplicitPrelude). Putting things in a global namespace like that is bad.
I see and agree. Scratch the Prelude part. David

Hello everyone, the discussion period for my proposal is now well over (started 2013-03-13), but there didn't seem to be much interest in it anyway, probably due to the relatively small impact of changes proposed (moving a couple of functions to more appropriate locations). As I am new to this process, I'm not sure how to proceed; I could have let it died without notice, but decided to send this final (?) notice. Greetings, David

I am +1 for exporting void from Data.Functor. I'm lukewarm about Data.Tuple.swap. I'm also +1 for moving ($>) from Control.Comonad into Data.Functor. I've had a number of users ask me for it over the years. On Wed, Apr 3, 2013 at 4:11 AM, David Luposchainsky < dluposchainsky@googlemail.com> wrote:
Hello everyone,
the discussion period for my proposal is now well over (started 2013-03-13), but there didn't seem to be much interest in it anyway, probably due to the relatively small impact of changes proposed (moving a couple of functions to more appropriate locations). As I am new to this process, I'm not sure how to proceed; I could have let it died without notice, but decided to send this final (?) notice.
Greetings, David
_______________________________________________ Libraries mailing list Libraries@haskell.org http://www.haskell.org/mailman/listinfo/libraries

So to sum it up, the current consensus seems to be the following: 1. Unanimously supported: Move "void" from Control.Monad to Data.Functor; re-export the function from Control.Monad for compatibility. 2. Scrap the tuple business. Modifying Prelude is not a good idea, and an irrefutable swap is based on principles that may require their own proposal (call it the "forceSwap" issue or something). 3. Unanimously supported: Move "($>) = flip (<$)" from Control.Comonad to Data.Functor. Greetings, David

Don't forget void is also exported from Foreign.Marshal.Error. I made a
proposal a while back about making it be a re-export of the Control.Monad
one so at least we wouldn't get name clashes, but I think it got forgotten
about due to lack of interest. I still think it's a good idea though...
On Wed, Apr 3, 2013 at 6:46 AM, Edward Kmett
I am +1 for exporting void from Data.Functor.
I'm lukewarm about Data.Tuple.swap.
I'm also +1 for moving ($>) from Control.Comonad into Data.Functor. I've had a number of users ask me for it over the years.
On Wed, Apr 3, 2013 at 4:11 AM, David Luposchainsky < dluposchainsky@googlemail.com> wrote:
Hello everyone,
the discussion period for my proposal is now well over (started 2013-03-13), but there didn't seem to be much interest in it anyway, probably due to the relatively small impact of changes proposed (moving a couple of functions to more appropriate locations). As I am new to this process, I'm not sure how to proceed; I could have let it died without notice, but decided to send this final (?) notice.
Greetings, David
_______________________________________________ Libraries mailing list Libraries@haskell.org http://www.haskell.org/mailman/listinfo/libraries
_______________________________________________ Libraries mailing list Libraries@haskell.org http://www.haskell.org/mailman/listinfo/libraries

+1 for fixing that as well (or even simply removing it as it is currently
deprecated)
On Wed, Apr 3, 2013 at 1:37 PM, Evan Laforge
Don't forget void is also exported from Foreign.Marshal.Error. I made a proposal a while back about making it be a re-export of the Control.Monad one so at least we wouldn't get name clashes, but I think it got forgotten about due to lack of interest. I still think it's a good idea though...
On Wed, Apr 3, 2013 at 6:46 AM, Edward Kmett
wrote: I am +1 for exporting void from Data.Functor.
I'm lukewarm about Data.Tuple.swap.
I'm also +1 for moving ($>) from Control.Comonad into Data.Functor. I've had a number of users ask me for it over the years.
On Wed, Apr 3, 2013 at 4:11 AM, David Luposchainsky < dluposchainsky@googlemail.com> wrote:
Hello everyone,
the discussion period for my proposal is now well over (started 2013-03-13), but there didn't seem to be much interest in it anyway, probably due to the relatively small impact of changes proposed (moving a couple of functions to more appropriate locations). As I am new to this process, I'm not sure how to proceed; I could have let it died without notice, but decided to send this final (?) notice.
Greetings, David
_______________________________________________ Libraries mailing list Libraries@haskell.org http://www.haskell.org/mailman/listinfo/libraries
_______________________________________________ Libraries mailing list Libraries@haskell.org http://www.haskell.org/mailman/listinfo/libraries

It's been deprecated for half a year now (as of Base 4.6, released september 2012). Is that enough time to safely remove it? On 2013-04-03 20:16, Edward Kmett wrote:
+1 for fixing that as well (or even simply removing it as it is currently deprecated)
On Wed, Apr 3, 2013 at 1:37 PM, Evan Laforge
mailto:qdunkan@gmail.com> wrote: Don't forget void is also exported from Foreign.Marshal.Error. I made a proposal a while back about making it be a re-export of the Control.Monad one so at least we wouldn't get name clashes, but I think it got forgotten about due to lack of interest. I still think it's a good idea though...

Then I'd probably wait, since there has been no major release in the interim.
Sent from my iPhone
On Apr 4, 2013, at 11:06 AM, David Luposchainsky
It's been deprecated for half a year now (as of Base 4.6, released september 2012). Is that enough time to safely remove it?
On 2013-04-03 20:16, Edward Kmett wrote:
+1 for fixing that as well (or even simply removing it as it is currently deprecated)
On Wed, Apr 3, 2013 at 1:37 PM, Evan Laforge
mailto:qdunkan@gmail.com> wrote: Don't forget void is also exported from Foreign.Marshal.Error. I made a proposal a while back about making it be a re-export of the Control.Monad one so at least we wouldn't get name clashes, but I think it got forgotten about due to lack of interest. I still think it's a good idea though...

Alright, so here's the last call before it's going to Trac: 1. Add the infixl 4 operator "($>) = flip (<$)" to Data.Functor. 2. Move Control.Monad.void to Data.Functor, and reexport it from Control.Monad for compatibility. (Foreign.Marshal.Error.void is redundant, but should be kept as it is only marked as deprecated for half a year.) The full discussion can be viewed at: http://markmail.org/message/cqdlle4l6npxs3jn Greetings, David

1. Add the infixl 4 operator "($>) = flip (<$)" to Data.Functor.
2. Move Control.Monad.void to Data.Functor, and reexport it from Control.Monad for compatibility. (Foreign.Marshal.Error.void is redundant, but should be kept as it is only marked as deprecated for half a year.)
One addition: Foreign.Marshal.Error.void should also be a re-export. This shouldn't break anyone's code, but would mean that people typing 'import Control.Monad; import Foreign' can use void without having to hide one or the other.

+1 for me
On Sat, Apr 6, 2013 at 12:51 PM, Evan Laforge
1. Add the infixl 4 operator "($>) = flip (<$)" to Data.Functor.
2. Move Control.Monad.void to Data.Functor, and reexport it from Control.Monad for compatibility. (Foreign.Marshal.Error.void is redundant, but should be kept as it is only marked as deprecated for half a year.)
One addition:
Foreign.Marshal.Error.void should also be a re-export. This shouldn't break anyone's code, but would mean that people typing 'import Control.Monad; import Foreign' can use void without having to hide one or the other.

* David Luposchainsky
Hello GHC HQ, hello mailing list,
there are a couple of basic functions that I think aren't where they should be.
1. void is currently in Control.Monad. However, it is defined only in terms of fmap (and therefore only has a Functor constraint). Although this function is often used in a monadic setting as ">> return ()", I really don't think Control.Monad is the right place for it.
+1 for re-export
2. a) swap is the only function from Data.Tuple that is not exported to Prelude. On #haskell, people are sometimes even surprised there /is/ a Data.Tuple, and redefine their own version of swap at need. I therefore suggest including Data.Tuple.swap in the Prelude.
The obvious downside of this change would of course be that it breaks code if there is a top-level user-defined version of it. Fixing this is of course trivial, but necessary.
-1, for the reasons already explained.
b) A related suggestion would be the addition of an irrefutable swap, (swap'?), defined as "swap ~(a,b) = (b,a)", and its addition to Prelude for the same reasons.
-1. Note that swap x behaves exactly as x — you can use refutable or irrefutable pattern matching on it and get the behaviour you desire. Your swap' is more limited (you can't recover the strict behaviour), and really combines two unrelated things. I'd +1 for Henning's forcePair if a better name is found (the word force is normally associated with being strict, although I can see why he used it here).
3. $>, a flipped version of <$, currently resides in Control.Comonad, but should be in Data.Functor. Applicative has <* and *>, Monad has >>= and =<<, and I personally keep redefining (or specifically importing) $> quite often, and I don't think I'm the only one.
+1 Roman

Roman Cheplyaka
I'd +1 for Henning's forcePair if a better name is found (the word force is normally associated with being strict, although I can see why he used it here).
btw, just thinking out loud, what about an infix operator such as (just as an example): (!.!) :: a -> b -> (a,b) a !.! b = a `seq` b `seq` (a,b) which let's you write a pair as ( exp1 !.! exp2 ) which has a bit of a resemblance to the standard tuple-construction syntax: ( exp1 , exp2 ) ? cheers, hvr

* Herbert Valerio Riedel
Roman Cheplyaka
writes: [...]
I'd +1 for Henning's forcePair if a better name is found (the word force is normally associated with being strict, although I can see why he used it here).
btw, just thinking out loud, what about an infix operator such as (just as an example):
(!.!) :: a -> b -> (a,b) a !.! b = a `seq` b `seq` (a,b)
which let's you write a pair as
( exp1 !.! exp2 )
which has a bit of a resemblance to the standard tuple-construction syntax:
( exp1 , exp2 )
?
Did you just fall victim of forcePair's name? :) It's about a different issue. Or is this meant as an unrelated proposal? Roman
participants (8)
-
David Luposchainsky
-
Edward A Kmett
-
Edward Kmett
-
Evan Laforge
-
Henning Thielemann
-
Herbert Valerio Riedel
-
Johan Tibell
-
Roman Cheplyaka