Proposal: add `on` to the Prelude

Every time I reach for Data.Function.on, I feel like a total dolt for having to import a module to get a function whose implementation is barely longer than the import. And it's a really good function too! Can we please add it to the Prelude? on :: (b -> b -> c) -> (a -> b) -> a -> a -> c (.*.) `on` f = \x y -> f x .*. f y

+1
On Tue, Sep 10, 2019, 5:53 PM David Feuer
Every time I reach for Data.Function.on, I feel like a total dolt for having to import a module to get a function whose implementation is barely longer than the import. And it's a really good function too! Can we please add it to the Prelude?
on :: (b -> b -> c) -> (a -> b) -> a -> a -> c (.*.) `on` f = \x y -> f x .*. f y _______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries

One note: this does conflict with some other libraries, for instance GTK2HS
On Tue, Sep 10, 2019 at 6:26 PM chessai .
+1
On Tue, Sep 10, 2019, 5:53 PM David Feuer
wrote: Every time I reach for Data.Function.on, I feel like a total dolt for having to import a module to get a function whose implementation is barely longer than the import. And it's a really good function too! Can we please add it to the Prelude?
on :: (b -> b -> c) -> (a -> b) -> a -> a -> c (.*.) `on` f = \x y -> f x .*. f y _______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
_______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries

Indeed, there are a lot more conflicts than I'd have expected. Ignoring
functions with the same type, Hoogle shows this name in the below packages.
I have no sense of the overall significance of the specific packages or
(equally importantly) of the `on` function within each.
haskell-gi-base:
on :: forall object info m . (GObject object, MonadIO m, SignalInfo info)
=> object -> SignalProxy object info -> HaskellCallbackType info -> m
SignalHandlerId
brick:
on :: Color -> Color -> Attr
esqueletto:
on :: SqlExpr (Value Bool) -> SqlQuery ()
relational-query (both):
on :: MonadQuery m => Predicate Flat -> m ()
on :: MonadQuery m => QueryA m (Predicate Flat) ()
threepenny-gui:
on :: (element -> Event a) -> element -> (a -> UI void) -> UI ()
miso:
on :: MisoString -> Decoder r -> (r -> action) -> Attribute action
wild-bind:
on :: i -> v -> Binder i v ()
massiv-io:
on :: Pixel X Bit
selda-postgresql:
on :: Text -> Text -> PGConnectInfo
On Tue, Sep 10, 2019, 6:42 PM Ryan Trinkle
One note: this does conflict with some other libraries, for instance GTK2HS
On Tue, Sep 10, 2019 at 6:26 PM chessai .
wrote: +1
On Tue, Sep 10, 2019, 5:53 PM David Feuer
wrote: Every time I reach for Data.Function.on, I feel like a total dolt for having to import a module to get a function whose implementation is barely longer than the import. And it's a really good function too! Can we please add it to the Prelude?
on :: (b -> b -> c) -> (a -> b) -> a -> a -> c (.*.) `on` f = \x y -> f x .*. f y _______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
_______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries

Hilariously, I'm mild -1 on this. Haskell is an extremely import-heavy
language. Anyone who isn't willing to just write their own mini-Prelude
should be ready to import things like `on`. Why isn't `for` exported in
Prelude? What about `&`? Both of these are extremely useful and common,
even moreso than *on*! And their implementation is *even shorter*. It's a
slippery slope.
On Tue, Sep 10, 2019 at 6:59 PM David Feuer
Indeed, there are a lot more conflicts than I'd have expected. Ignoring functions with the same type, Hoogle shows this name in the below packages. I have no sense of the overall significance of the specific packages or (equally importantly) of the `on` function within each.
haskell-gi-base: on :: forall object info m . (GObject object, MonadIO m, SignalInfo info) => object -> SignalProxy object info -> HaskellCallbackType info -> m SignalHandlerId
brick: on :: Color -> Color -> Attr
esqueletto: on :: SqlExpr (Value Bool) -> SqlQuery ()
relational-query (both): on :: MonadQuery m => Predicate Flat -> m () on :: MonadQuery m => QueryA m (Predicate Flat) ()
threepenny-gui: on :: (element -> Event a) -> element -> (a -> UI void) -> UI ()
miso: on :: MisoString -> Decoder r -> (r -> action) -> Attribute action
wild-bind: on :: i -> v -> Binder i v ()
massiv-io: on :: Pixel X Bit
selda-postgresql: on :: Text -> Text -> PGConnectInfo
On Tue, Sep 10, 2019, 6:42 PM Ryan Trinkle
wrote: One note: this does conflict with some other libraries, for instance GTK2HS
On Tue, Sep 10, 2019 at 6:26 PM chessai .
wrote: +1
On Tue, Sep 10, 2019, 5:53 PM David Feuer
wrote: Every time I reach for Data.Function.on, I feel like a total dolt for having to import a module to get a function whose implementation is barely longer than the import. And it's a really good function too! Can we please add it to the Prelude?
on :: (b -> b -> c) -> (a -> b) -> a -> a -> c (.*.) `on` f = \x y -> f x .*. f y _______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
_______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
_______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries

I would also prefer if (&) and `for` were exported from the Prelude.
On Tue, Sep 10, 2019, 9:33 PM Elliot Cameron
Hilariously, I'm mild -1 on this. Haskell is an extremely import-heavy language. Anyone who isn't willing to just write their own mini-Prelude should be ready to import things like `on`. Why isn't `for` exported in Prelude? What about `&`? Both of these are extremely useful and common, even moreso than *on*! And their implementation is *even shorter*. It's a slippery slope.
On Tue, Sep 10, 2019 at 6:59 PM David Feuer
wrote: Indeed, there are a lot more conflicts than I'd have expected. Ignoring functions with the same type, Hoogle shows this name in the below packages. I have no sense of the overall significance of the specific packages or (equally importantly) of the `on` function within each.
haskell-gi-base: on :: forall object info m . (GObject object, MonadIO m, SignalInfo info) => object -> SignalProxy object info -> HaskellCallbackType info -> m SignalHandlerId
brick: on :: Color -> Color -> Attr
esqueletto: on :: SqlExpr (Value Bool) -> SqlQuery ()
relational-query (both): on :: MonadQuery m => Predicate Flat -> m () on :: MonadQuery m => QueryA m (Predicate Flat) ()
threepenny-gui: on :: (element -> Event a) -> element -> (a -> UI void) -> UI ()
miso: on :: MisoString -> Decoder r -> (r -> action) -> Attribute action
wild-bind: on :: i -> v -> Binder i v ()
massiv-io: on :: Pixel X Bit
selda-postgresql: on :: Text -> Text -> PGConnectInfo
On Tue, Sep 10, 2019, 6:42 PM Ryan Trinkle
wrote: One note: this does conflict with some other libraries, for instance GTK2HS
On Tue, Sep 10, 2019 at 6:26 PM chessai .
wrote: +1
On Tue, Sep 10, 2019, 5:53 PM David Feuer
wrote: Every time I reach for Data.Function.on, I feel like a total dolt for having to import a module to get a function whose implementation is barely longer than the import. And it's a really good function too! Can we please add it to the Prelude?
on :: (b -> b -> c) -> (a -> b) -> a -> a -> c (.*.) `on` f = \x y -> f x .*. f y _______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
_______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
_______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
_______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries

Part of me would too...but I just don't know when this line of reasoning
stops. Do we add (>>>) and (<<<) from Category too? Then (&&&)? Of course
then we might want first, second... Oh and (<$) isn't exported but ($>) is?
Fix that too. Then come join, fix, void, when, unless, bool, fromMaybe.....
I've come to the conclusion that Prelude should err on the side of very
small because Haskell is just too diverse a place to expect everyone to
agree on all these little things. We should all be making project-specific
Preludes instead IMO.
On Tue, Sep 10, 2019 at 9:41 PM chessai .
I would also prefer if (&) and `for` were exported from the Prelude.
On Tue, Sep 10, 2019, 9:33 PM Elliot Cameron
wrote: Hilariously, I'm mild -1 on this. Haskell is an extremely import-heavy language. Anyone who isn't willing to just write their own mini-Prelude should be ready to import things like `on`. Why isn't `for` exported in Prelude? What about `&`? Both of these are extremely useful and common, even moreso than *on*! And their implementation is *even shorter*. It's a slippery slope.
On Tue, Sep 10, 2019 at 6:59 PM David Feuer
wrote: Indeed, there are a lot more conflicts than I'd have expected. Ignoring functions with the same type, Hoogle shows this name in the below packages. I have no sense of the overall significance of the specific packages or (equally importantly) of the `on` function within each.
haskell-gi-base: on :: forall object info m . (GObject object, MonadIO m, SignalInfo info) => object -> SignalProxy object info -> HaskellCallbackType info -> m SignalHandlerId
brick: on :: Color -> Color -> Attr
esqueletto: on :: SqlExpr (Value Bool) -> SqlQuery ()
relational-query (both): on :: MonadQuery m => Predicate Flat -> m () on :: MonadQuery m => QueryA m (Predicate Flat) ()
threepenny-gui: on :: (element -> Event a) -> element -> (a -> UI void) -> UI ()
miso: on :: MisoString -> Decoder r -> (r -> action) -> Attribute action
wild-bind: on :: i -> v -> Binder i v ()
massiv-io: on :: Pixel X Bit
selda-postgresql: on :: Text -> Text -> PGConnectInfo
On Tue, Sep 10, 2019, 6:42 PM Ryan Trinkle
wrote: One note: this does conflict with some other libraries, for instance GTK2HS
On Tue, Sep 10, 2019 at 6:26 PM chessai .
wrote: +1
On Tue, Sep 10, 2019, 5:53 PM David Feuer
wrote: Every time I reach for Data.Function.on, I feel like a total dolt for having to import a module to get a function whose implementation is barely longer than the import. And it's a really good function too! Can we please add it to the Prelude?
on :: (b -> b -> c) -> (a -> b) -> a -> a -> c (.*.) `on` f = \x y -> f x .*. f y _______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
_______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
_______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
_______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries

I agree with your general conservatism, but I think some of these things
are not like the others. I like `on` for the Prelude because, despite its
size, it carries with it the idea of carrying a relationship between two
values through a function. Notably, for *any* function f,
eq `on` f defines a decidable equivalence relation if eq does.
cmp `on` f defines a decidable partial order if cmp does.
d `on` f is a pseudometric if d is.
What a beautiful and useful concept! I find it much harder to get excited
about the idea of flipping function application.
On Tue, Sep 10, 2019, 9:50 PM Elliot Cameron
Part of me would too...but I just don't know when this line of reasoning stops. Do we add (>>>) and (<<<) from Category too? Then (&&&)? Of course then we might want first, second... Oh and (<$) isn't exported but ($>) is? Fix that too. Then come join, fix, void, when, unless, bool, fromMaybe..... I've come to the conclusion that Prelude should err on the side of very small because Haskell is just too diverse a place to expect everyone to agree on all these little things. We should all be making project-specific Preludes instead IMO.
On Tue, Sep 10, 2019 at 9:41 PM chessai .
wrote: I would also prefer if (&) and `for` were exported from the Prelude.
On Tue, Sep 10, 2019, 9:33 PM Elliot Cameron
wrote: Hilariously, I'm mild -1 on this. Haskell is an extremely import-heavy language. Anyone who isn't willing to just write their own mini-Prelude should be ready to import things like `on`. Why isn't `for` exported in Prelude? What about `&`? Both of these are extremely useful and common, even moreso than *on*! And their implementation is *even shorter*. It's a slippery slope.
On Tue, Sep 10, 2019 at 6:59 PM David Feuer
wrote: Indeed, there are a lot more conflicts than I'd have expected. Ignoring functions with the same type, Hoogle shows this name in the below packages. I have no sense of the overall significance of the specific packages or (equally importantly) of the `on` function within each.
haskell-gi-base: on :: forall object info m . (GObject object, MonadIO m, SignalInfo info) => object -> SignalProxy object info -> HaskellCallbackType info -> m SignalHandlerId
brick: on :: Color -> Color -> Attr
esqueletto: on :: SqlExpr (Value Bool) -> SqlQuery ()
relational-query (both): on :: MonadQuery m => Predicate Flat -> m () on :: MonadQuery m => QueryA m (Predicate Flat) ()
threepenny-gui: on :: (element -> Event a) -> element -> (a -> UI void) -> UI ()
miso: on :: MisoString -> Decoder r -> (r -> action) -> Attribute action
wild-bind: on :: i -> v -> Binder i v ()
massiv-io: on :: Pixel X Bit
selda-postgresql: on :: Text -> Text -> PGConnectInfo
On Tue, Sep 10, 2019, 6:42 PM Ryan Trinkle
wrote: One note: this does conflict with some other libraries, for instance GTK2HS
On Tue, Sep 10, 2019 at 6:26 PM chessai .
wrote: +1
On Tue, Sep 10, 2019, 5:53 PM David Feuer
wrote: > Every time I reach for Data.Function.on, I feel like a total dolt > for having to import a module to get a function whose implementation is > barely longer than the import. And it's a really good function too! Can we > please add it to the Prelude? > > on :: (b -> b -> c) -> (a -> b) -> a -> a -> c > (.*.) `on` f = \x y -> f x .*. f y > _______________________________________________ > Libraries mailing list > Libraries@haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries > _______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
_______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
_______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries

That's certainly true but I'm not sure what that has to do with being in
Prelude. If anything, I'd expect Prelude to be home to the *least* exciting
things because no one wants to bother talking about them.
On Tue, Sep 10, 2019, 10:20 PM David Feuer
I agree with your general conservatism, but I think some of these things are not like the others. I like `on` for the Prelude because, despite its size, it carries with it the idea of carrying a relationship between two values through a function. Notably, for *any* function f,
eq `on` f defines a decidable equivalence relation if eq does. cmp `on` f defines a decidable partial order if cmp does. d `on` f is a pseudometric if d is.
What a beautiful and useful concept! I find it much harder to get excited about the idea of flipping function application.
On Tue, Sep 10, 2019, 9:50 PM Elliot Cameron
wrote: Part of me would too...but I just don't know when this line of reasoning stops. Do we add (>>>) and (<<<) from Category too? Then (&&&)? Of course then we might want first, second... Oh and (<$) isn't exported but ($>) is? Fix that too. Then come join, fix, void, when, unless, bool, fromMaybe..... I've come to the conclusion that Prelude should err on the side of very small because Haskell is just too diverse a place to expect everyone to agree on all these little things. We should all be making project-specific Preludes instead IMO.
On Tue, Sep 10, 2019 at 9:41 PM chessai .
wrote: I would also prefer if (&) and `for` were exported from the Prelude.
On Tue, Sep 10, 2019, 9:33 PM Elliot Cameron
wrote: Hilariously, I'm mild -1 on this. Haskell is an extremely import-heavy language. Anyone who isn't willing to just write their own mini-Prelude should be ready to import things like `on`. Why isn't `for` exported in Prelude? What about `&`? Both of these are extremely useful and common, even moreso than *on*! And their implementation is *even shorter*. It's a slippery slope.
On Tue, Sep 10, 2019 at 6:59 PM David Feuer
wrote: Indeed, there are a lot more conflicts than I'd have expected. Ignoring functions with the same type, Hoogle shows this name in the below packages. I have no sense of the overall significance of the specific packages or (equally importantly) of the `on` function within each.
haskell-gi-base: on :: forall object info m . (GObject object, MonadIO m, SignalInfo info) => object -> SignalProxy object info -> HaskellCallbackType info -> m SignalHandlerId
brick: on :: Color -> Color -> Attr
esqueletto: on :: SqlExpr (Value Bool) -> SqlQuery ()
relational-query (both): on :: MonadQuery m => Predicate Flat -> m () on :: MonadQuery m => QueryA m (Predicate Flat) ()
threepenny-gui: on :: (element -> Event a) -> element -> (a -> UI void) -> UI ()
miso: on :: MisoString -> Decoder r -> (r -> action) -> Attribute action
wild-bind: on :: i -> v -> Binder i v ()
massiv-io: on :: Pixel X Bit
selda-postgresql: on :: Text -> Text -> PGConnectInfo
On Tue, Sep 10, 2019, 6:42 PM Ryan Trinkle
wrote: One note: this does conflict with some other libraries, for instance GTK2HS
On Tue, Sep 10, 2019 at 6:26 PM chessai .
wrote: > +1 > > On Tue, Sep 10, 2019, 5:53 PM David Feuer
> wrote: > >> Every time I reach for Data.Function.on, I feel like a total dolt >> for having to import a module to get a function whose implementation is >> barely longer than the import. And it's a really good function too! Can we >> please add it to the Prelude? >> >> on :: (b -> b -> c) -> (a -> b) -> a -> a -> c >> (.*.) `on` f = \x y -> f x .*. f y >> _______________________________________________ >> Libraries mailing list >> Libraries@haskell.org >> http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries >> > _______________________________________________ > Libraries mailing list > Libraries@haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries > _______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries _______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries

+1
Am Mi., 11. Sept. 2019 um 01:41 Uhr schrieb chessai . : I would also prefer if (&) and `for` were exported from the Prelude. On Tue, Sep 10, 2019, 9:33 PM Elliot Cameron Hilariously, I'm mild -1 on this. Haskell is an extremely import-heavy
language. Anyone who isn't willing to just write their own mini-Prelude
should be ready to import things like `on`. Why isn't `for` exported in
Prelude? What about `&`? Both of these are extremely useful and common,
even moreso than *on*! And their implementation is *even shorter*. It's a
slippery slope. On Tue, Sep 10, 2019 at 6:59 PM David Feuer Indeed, there are a lot more conflicts than I'd have expected. Ignoring
functions with the same type, Hoogle shows this name in the below packages.
I have no sense of the overall significance of the specific packages or
(equally importantly) of the `on` function within each. haskell-gi-base:
on :: forall object info m . (GObject object, MonadIO m, SignalInfo
info) => object -> SignalProxy object info -> HaskellCallbackType info -> m
SignalHandlerId brick:
on :: Color -> Color -> Attr esqueletto:
on :: SqlExpr (Value Bool) -> SqlQuery () relational-query (both):
on :: MonadQuery m => Predicate Flat -> m ()
on :: MonadQuery m => QueryA m (Predicate Flat) () threepenny-gui:
on :: (element -> Event a) -> element -> (a -> UI void) -> UI () miso:
on :: MisoString -> Decoder r -> (r -> action) -> Attribute action wild-bind:
on :: i -> v -> Binder i v () massiv-io:
on :: Pixel X Bit selda-postgresql:
on :: Text -> Text -> PGConnectInfo On Tue, Sep 10, 2019, 6:42 PM Ryan Trinkle One note: this does conflict with some other libraries, for instance
GTK2HS On Tue, Sep 10, 2019 at 6:26 PM chessai . +1 On Tue, Sep 10, 2019, 5:53 PM David Feuer Every time I reach for Data.Function.on, I feel like a total dolt for
having to import a module to get a function whose implementation is barely
longer than the import. And it's a really good function too! Can we please
add it to the Prelude? on :: (b -> b -> c) -> (a -> b) -> a -> a -> c
(.*.) `on` f = \x y -> f x .*. f y
_______________________________________________
Libraries mailing list
Libraries@haskell.org
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries _______________________________________________
Libraries mailing list
Libraries@haskell.org
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries _______________________________________________
Libraries mailing list
Libraries@haskell.org
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries _______________________________________________
Libraries mailing list
Libraries@haskell.org
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries _______________________________________________
Libraries mailing list
Libraries@haskell.org
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries

The number of name conflicts here has me rather conflicted.
To date, we've been treating the Prelude is a very precious common
namespace.
Every name it takes is a significant cost because now every other use of
the name, pre-existing or not, has to explicitly _hide_ the import from the
Prelude, not just in their library code, but in all the code that uses the
library.
By comparison, the Data.List.singleton issue was comparatively clash-free
as most uses of a combinator with the same name were already qualified, and
we were able to mitigate the remaining issues, by deciding that the module
in question was intended to become qualified after a short cycle, so no
"global" name is being used up.
Here, we're finding several conflicting combinators, and the cost is
significantly higher for each of the existing consumers of that name to
work around.
It strikes me that in the end there'd be a lot of churn, as all existing
users of conflicting versions of this very short punchy name would have to
move to a new name or endure a ton of Prelude hiding clauses all over their
code, in both library and consumer code.
This leaves me inclined to a -1.
There are combinators I'm somewhat inclined to push into Prelude after an
appropriate referendum, e.g. traverse_ or sequence_ which do a lot of work
and are quite conspicuous in their absence, when a
worse-for-many-applications but comparable tool is closer to hand, but the
slight pain of explicitly importing 'on' seems pretty reasonable given the
combination of its somewhat confusing at first idiomatic usage, and the
somewhat broadly spread existing name conflicts.
-Edward
On Tue, Sep 10, 2019 at 3:59 PM David Feuer
Indeed, there are a lot more conflicts than I'd have expected. Ignoring functions with the same type, Hoogle shows this name in the below packages. I have no sense of the overall significance of the specific packages or (equally importantly) of the `on` function within each.
haskell-gi-base: on :: forall object info m . (GObject object, MonadIO m, SignalInfo info) => object -> SignalProxy object info -> HaskellCallbackType info -> m SignalHandlerId
brick: on :: Color -> Color -> Attr
esqueletto: on :: SqlExpr (Value Bool) -> SqlQuery ()
relational-query (both): on :: MonadQuery m => Predicate Flat -> m () on :: MonadQuery m => QueryA m (Predicate Flat) ()
threepenny-gui: on :: (element -> Event a) -> element -> (a -> UI void) -> UI ()
miso: on :: MisoString -> Decoder r -> (r -> action) -> Attribute action
wild-bind: on :: i -> v -> Binder i v ()
massiv-io: on :: Pixel X Bit
selda-postgresql: on :: Text -> Text -> PGConnectInfo
On Tue, Sep 10, 2019, 6:42 PM Ryan Trinkle
wrote: One note: this does conflict with some other libraries, for instance GTK2HS
On Tue, Sep 10, 2019 at 6:26 PM chessai .
wrote: +1
On Tue, Sep 10, 2019, 5:53 PM David Feuer
wrote: Every time I reach for Data.Function.on, I feel like a total dolt for having to import a module to get a function whose implementation is barely longer than the import. And it's a really good function too! Can we please add it to the Prelude?
on :: (b -> b -> c) -> (a -> b) -> a -> a -> c (.*.) `on` f = \x y -> f x .*. f y _______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
_______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
_______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries

Am Mi., 11. Sept. 2019 um 02:18 Uhr schrieb Edward Kmett
There are combinators I'm somewhat inclined to push into Prelude after an appropriate referendum, e.g. traverse_ or sequence_ which do a lot of work and are quite conspicuous in their absence, when a worse-for-many-applications but comparable tool is closer to hand, but the slight pain of explicitly importing 'on' seems pretty reasonable given the combination of its somewhat confusing at first idiomatic usage, and the somewhat broadly spread existing name conflicts.
This slight pain of writing "import Data.Function (on)" as you call is why I and probably most other people don't bother using "on". But why is such a trivial combinator that's cheaper to define locally than to import even defined in the base library if the pain of using it outweighs its usefulness and there's just a handful of people at best using it?

+1 for adding `on` to the Prelude. On 2019-09-11 00:59, David Feuer wrote:
Indeed, there are a lot more conflicts than I'd have expected. Ignoring functions with the same type, Hoogle shows this name in the below packages. I have no sense of the overall significance of the specific packages or (equally importantly) of the `on` function within each.
haskell-gi-base: on :: forall object info m . (GObject object, MonadIO m, SignalInfo info) => object -> SignalProxy object info -> HaskellCallbackType info -> m SignalHandlerId
brick: on :: Color -> Color -> Attr
esqueletto: on :: SqlExpr (Value Bool) -> SqlQuery ()
relational-query (both): on :: MonadQuery m => Predicate Flat -> m () on :: MonadQuery m => QueryA m (Predicate Flat) ()
threepenny-gui: on :: (element -> Event a) -> element -> (a -> UI void) -> UI ()
miso: on :: MisoString -> Decoder r -> (r -> action) -> Attribute action
wild-bind: on :: i -> v -> Binder i v ()
massiv-io: on :: Pixel X Bit
selda-postgresql: on :: Text -> Text -> PGConnectInfo
On Tue, Sep 10, 2019, 6:42 PM Ryan Trinkle
mailto:ryan.trinkle@gmail.com> wrote: One note: this does conflict with some other libraries, for instance GTK2HS
On Tue, Sep 10, 2019 at 6:26 PM chessai .
mailto:chessai1996@gmail.com> wrote: +1
On Tue, Sep 10, 2019, 5:53 PM David Feuer
mailto:david.feuer@gmail.com> wrote: Every time I reach for Data.Function.on, I feel like a total dolt for having to import a module to get a function whose implementation is barely longer than the import. And it's a really good function too! Can we please add it to the Prelude?
on :: (b -> b -> c) -> (a -> b) -> a -> a -> c (.*.) `on` f = \x y -> f x .*. f y _______________________________________________ Libraries mailing list Libraries@haskell.org mailto:Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
_______________________________________________ Libraries mailing list Libraries@haskell.org mailto:Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
_______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries

For whatever it's worth, the unidiomatic but arguably more logical name
`on2` has no hits on Hoogle.
On Tue, Sep 10, 2019, 6:59 PM David Feuer
Indeed, there are a lot more conflicts than I'd have expected. Ignoring functions with the same type, Hoogle shows this name in the below packages. I have no sense of the overall significance of the specific packages or (equally importantly) of the `on` function within each.
haskell-gi-base: on :: forall object info m . (GObject object, MonadIO m, SignalInfo info) => object -> SignalProxy object info -> HaskellCallbackType info -> m SignalHandlerId
brick: on :: Color -> Color -> Attr
esqueletto: on :: SqlExpr (Value Bool) -> SqlQuery ()
relational-query (both): on :: MonadQuery m => Predicate Flat -> m () on :: MonadQuery m => QueryA m (Predicate Flat) ()
threepenny-gui: on :: (element -> Event a) -> element -> (a -> UI void) -> UI ()
miso: on :: MisoString -> Decoder r -> (r -> action) -> Attribute action
wild-bind: on :: i -> v -> Binder i v ()
massiv-io: on :: Pixel X Bit
selda-postgresql: on :: Text -> Text -> PGConnectInfo
On Tue, Sep 10, 2019, 6:42 PM Ryan Trinkle
wrote: One note: this does conflict with some other libraries, for instance GTK2HS
On Tue, Sep 10, 2019 at 6:26 PM chessai .
wrote: +1
On Tue, Sep 10, 2019, 5:53 PM David Feuer
wrote: Every time I reach for Data.Function.on, I feel like a total dolt for having to import a module to get a function whose implementation is barely longer than the import. And it's a really good function too! Can we please add it to the Prelude?
on :: (b -> b -> c) -> (a -> b) -> a -> a -> c (.*.) `on` f = \x y -> f x .*. f y _______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
_______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries

You might be on2 something.
But then you rename it in Data.Function too and break backward compat??
On Thu, Sep 12, 2019 at 10:55 AM David Feuer
For whatever it's worth, the unidiomatic but arguably more logical name `on2` has no hits on Hoogle.
On Tue, Sep 10, 2019, 6:59 PM David Feuer
wrote: Indeed, there are a lot more conflicts than I'd have expected. Ignoring functions with the same type, Hoogle shows this name in the below packages. I have no sense of the overall significance of the specific packages or (equally importantly) of the `on` function within each.
haskell-gi-base: on :: forall object info m . (GObject object, MonadIO m, SignalInfo info) => object -> SignalProxy object info -> HaskellCallbackType info -> m SignalHandlerId
brick: on :: Color -> Color -> Attr
esqueletto: on :: SqlExpr (Value Bool) -> SqlQuery ()
relational-query (both): on :: MonadQuery m => Predicate Flat -> m () on :: MonadQuery m => QueryA m (Predicate Flat) ()
threepenny-gui: on :: (element -> Event a) -> element -> (a -> UI void) -> UI ()
miso: on :: MisoString -> Decoder r -> (r -> action) -> Attribute action
wild-bind: on :: i -> v -> Binder i v ()
massiv-io: on :: Pixel X Bit
selda-postgresql: on :: Text -> Text -> PGConnectInfo
On Tue, Sep 10, 2019, 6:42 PM Ryan Trinkle
wrote: One note: this does conflict with some other libraries, for instance GTK2HS
On Tue, Sep 10, 2019 at 6:26 PM chessai .
wrote: +1
On Tue, Sep 10, 2019, 5:53 PM David Feuer
wrote: Every time I reach for Data.Function.on, I feel like a total dolt for having to import a module to get a function whose implementation is barely longer than the import. And it's a really good function too! Can we please add it to the Prelude?
on :: (b -> b -> c) -> (a -> b) -> a -> a -> c (.*.) `on` f = \x y -> f x .*. f y _______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
_______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
_______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries

No, there's certainly no need to remove the existing function.
On Thu, Sep 12, 2019, 10:57 AM Elliot Cameron
You might be on2 something.
But then you rename it in Data.Function too and break backward compat??
On Thu, Sep 12, 2019 at 10:55 AM David Feuer
wrote: For whatever it's worth, the unidiomatic but arguably more logical name `on2` has no hits on Hoogle.
On Tue, Sep 10, 2019, 6:59 PM David Feuer
wrote: Indeed, there are a lot more conflicts than I'd have expected. Ignoring functions with the same type, Hoogle shows this name in the below packages. I have no sense of the overall significance of the specific packages or (equally importantly) of the `on` function within each.
haskell-gi-base: on :: forall object info m . (GObject object, MonadIO m, SignalInfo info) => object -> SignalProxy object info -> HaskellCallbackType info -> m SignalHandlerId
brick: on :: Color -> Color -> Attr
esqueletto: on :: SqlExpr (Value Bool) -> SqlQuery ()
relational-query (both): on :: MonadQuery m => Predicate Flat -> m () on :: MonadQuery m => QueryA m (Predicate Flat) ()
threepenny-gui: on :: (element -> Event a) -> element -> (a -> UI void) -> UI ()
miso: on :: MisoString -> Decoder r -> (r -> action) -> Attribute action
wild-bind: on :: i -> v -> Binder i v ()
massiv-io: on :: Pixel X Bit
selda-postgresql: on :: Text -> Text -> PGConnectInfo
On Tue, Sep 10, 2019, 6:42 PM Ryan Trinkle
wrote: One note: this does conflict with some other libraries, for instance GTK2HS
On Tue, Sep 10, 2019 at 6:26 PM chessai .
wrote: +1
On Tue, Sep 10, 2019, 5:53 PM David Feuer
wrote: Every time I reach for Data.Function.on, I feel like a total dolt for having to import a module to get a function whose implementation is barely longer than the import. And it's a really good function too! Can we please add it to the Prelude?
on :: (b -> b -> c) -> (a -> b) -> a -> a -> c (.*.) `on` f = \x y -> f x .*. f y _______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
_______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
_______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries

Bleh. Now we have two functions that do the same thing, both in base... I
don't want "on" in prelude but this seems far worse to me than the original
proposal. Let's stick with that one for now and if it dies you can propose
this separately? :D
On Thu, Sep 12, 2019 at 11:15 AM David Feuer
No, there's certainly no need to remove the existing function.
On Thu, Sep 12, 2019, 10:57 AM Elliot Cameron
wrote: You might be on2 something.
But then you rename it in Data.Function too and break backward compat??
On Thu, Sep 12, 2019 at 10:55 AM David Feuer
wrote: For whatever it's worth, the unidiomatic but arguably more logical name `on2` has no hits on Hoogle.
On Tue, Sep 10, 2019, 6:59 PM David Feuer
wrote: Indeed, there are a lot more conflicts than I'd have expected. Ignoring functions with the same type, Hoogle shows this name in the below packages. I have no sense of the overall significance of the specific packages or (equally importantly) of the `on` function within each.
haskell-gi-base: on :: forall object info m . (GObject object, MonadIO m, SignalInfo info) => object -> SignalProxy object info -> HaskellCallbackType info -> m SignalHandlerId
brick: on :: Color -> Color -> Attr
esqueletto: on :: SqlExpr (Value Bool) -> SqlQuery ()
relational-query (both): on :: MonadQuery m => Predicate Flat -> m () on :: MonadQuery m => QueryA m (Predicate Flat) ()
threepenny-gui: on :: (element -> Event a) -> element -> (a -> UI void) -> UI ()
miso: on :: MisoString -> Decoder r -> (r -> action) -> Attribute action
wild-bind: on :: i -> v -> Binder i v ()
massiv-io: on :: Pixel X Bit
selda-postgresql: on :: Text -> Text -> PGConnectInfo
On Tue, Sep 10, 2019, 6:42 PM Ryan Trinkle
wrote: One note: this does conflict with some other libraries, for instance GTK2HS
On Tue, Sep 10, 2019 at 6:26 PM chessai .
wrote: +1
On Tue, Sep 10, 2019, 5:53 PM David Feuer
wrote: > Every time I reach for Data.Function.on, I feel like a total dolt > for having to import a module to get a function whose implementation is > barely longer than the import. And it's a really good function too! Can we > please add it to the Prelude? > > on :: (b -> b -> c) -> (a -> b) -> a -> a -> c > (.*.) `on` f = \x y -> f x .*. f y > _______________________________________________ > Libraries mailing list > Libraries@haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries > _______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
_______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries

I don't use `on` because my usecases are covered by `sortOn` and
`groupWith`; I can only recall a couple of cases when I had to resort to
`on`, and I don't often see it in others' code either, or if I do it's
often in conjuction with `sort` anyway.
I have, however, seen people use `on` because it's /cute/, and it's
definitely not something I would want to encourage.
On the other hand, `for` and `when` and `and` and other common words are
taken already and it almost never creates any problems for me, so I would
not mind having `on` stolen either.
So, I'm -0.5 on the proposal.
On Thu, Sep 12, 2019, 18:20 Elliot Cameron
Bleh. Now we have two functions that do the same thing, both in base... I don't want "on" in prelude but this seems far worse to me than the original proposal. Let's stick with that one for now and if it dies you can propose this separately? :D
On Thu, Sep 12, 2019 at 11:15 AM David Feuer
wrote: No, there's certainly no need to remove the existing function.
On Thu, Sep 12, 2019, 10:57 AM Elliot Cameron
wrote: You might be on2 something.
But then you rename it in Data.Function too and break backward compat??
On Thu, Sep 12, 2019 at 10:55 AM David Feuer
wrote: For whatever it's worth, the unidiomatic but arguably more logical name `on2` has no hits on Hoogle.
On Tue, Sep 10, 2019, 6:59 PM David Feuer
wrote: Indeed, there are a lot more conflicts than I'd have expected. Ignoring functions with the same type, Hoogle shows this name in the below packages. I have no sense of the overall significance of the specific packages or (equally importantly) of the `on` function within each.
haskell-gi-base: on :: forall object info m . (GObject object, MonadIO m, SignalInfo info) => object -> SignalProxy object info -> HaskellCallbackType info -> m SignalHandlerId
brick: on :: Color -> Color -> Attr
esqueletto: on :: SqlExpr (Value Bool) -> SqlQuery ()
relational-query (both): on :: MonadQuery m => Predicate Flat -> m () on :: MonadQuery m => QueryA m (Predicate Flat) ()
threepenny-gui: on :: (element -> Event a) -> element -> (a -> UI void) -> UI ()
miso: on :: MisoString -> Decoder r -> (r -> action) -> Attribute action
wild-bind: on :: i -> v -> Binder i v ()
massiv-io: on :: Pixel X Bit
selda-postgresql: on :: Text -> Text -> PGConnectInfo
On Tue, Sep 10, 2019, 6:42 PM Ryan Trinkle
wrote: One note: this does conflict with some other libraries, for instance GTK2HS
On Tue, Sep 10, 2019 at 6:26 PM chessai .
wrote: > +1 > > On Tue, Sep 10, 2019, 5:53 PM David Feuer
> wrote: > >> Every time I reach for Data.Function.on, I feel like a total dolt >> for having to import a module to get a function whose implementation is >> barely longer than the import. And it's a really good function too! Can we >> please add it to the Prelude? >> >> on :: (b -> b -> c) -> (a -> b) -> a -> a -> c >> (.*.) `on` f = \x y -> f x .*. f y >> _______________________________________________ >> Libraries mailing list >> Libraries@haskell.org >> http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries >> > _______________________________________________ > Libraries mailing list > Libraries@haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries > _______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries _______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries

On Tue, 10 Sep 2019, David Feuer wrote:
Indeed, there are a lot more conflicts than I'd have expected. Ignoring functions with the same type, Hoogle shows this name in the below packages.
It's not only about top-level functions named 'on'. If I use 'on' as a local variable, then I get warnings about local redefinitions of the global Prelude.on.

Am Di., 10. Sept. 2019 um 21:53 Uhr schrieb David Feuer < david.feuer@gmail.com>:
Every time I reach for Data.Function.on, I feel like a total dolt for having to import a module to get a function whose implementation is barely longer than the import. And it's a really good function too! Can we please add it to the Prelude?
Agreed. This function makes only sense to have if the cost of getting it into scope doesn't outweigh its benefit and therefore I support this proposal which makes a lot more sense than the pointless singleton proposal.

Describing another's proposal as "pointless" contributes to the perception
that this is an unfriendly community. Please don't do that! If you want to
explain why you think Proposal X is more worthy than Proposal Y, you should
do so constructively and sensitively.
On Tue, Sep 10, 2019, 6:42 PM Helmut Schmidt
Am Di., 10. Sept. 2019 um 21:53 Uhr schrieb David Feuer < david.feuer@gmail.com>:
Every time I reach for Data.Function.on, I feel like a total dolt for having to import a module to get a function whose implementation is barely longer than the import. And it's a really good function too! Can we please add it to the Prelude?
Agreed. This function makes only sense to have if the cost of getting it into scope doesn't outweigh its benefit and therefore I support this proposal which makes a lot more sense than the pointless singleton proposal.

+1 from me
We export `on` from `relude` by default and didn't have any problems so far:
*
http://hackage.haskell.org/package/relude-0.5.0/docs/Relude-Function.html#v:...
I believe that this proposal hits the same wall like all other proposals
regarding changes to the standard library — it's not clear, what are
Prelude goals. Should it be minimal and provide only fundamental things, or
should it enforce commonly used idioms? I think that the `on` function from
this proposal is the most widely used version of any other function with
the same name. When I see `on` in the code, I first expect the version from
`base`, not from some external library with a different type. Implementing
your own `on` in your library and forcing users to use it makes code hard
to read and reason about. Especially when people are using implicit imports
— good luck figuring out which one `on` is used! I believe that if `on` was
already imported by `Prelude`, fewer people would introduce identifiers
with this name. Which means that exporting `on` from `Prelude` is an
excellent thing to do if `Prelude` wants to force idiomatic usage of this
function.
On Wed, Sep 11, 2019 at 1:53 AM David Feuer
Every time I reach for Data.Function.on, I feel like a total dolt for having to import a module to get a function whose implementation is barely longer than the import. And it's a really good function too! Can we please add it to the Prelude?
on :: (b -> b -> c) -> (a -> b) -> a -> a -> c (.*.) `on` f = \x y -> f x .*. f y _______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries

Hello everyone,
To provide another data-point; in my "Prelude module replacement" package
http://hackage.haskell.org/package/Prelude
which encodes a common standard vocabulary from `base` I've observed in my
own projects over the years where I often keep a "local prelude" module for
the purpose of establishing a project-specific common vocabulary. Under
these constraints, `on` as well as `&` happens to be such a common
vocabulary which I expect to have in my default scope, and thus is
reexported from the "Prelude" module:
http://hackage.haskell.org/package/Prelude-0.1.0.1/docs/Prelude.html#g:21
But then again, since it's so easy to implement your own opinionated
"Prelude" replacement (either project-local or as a package on Hackage),
and subjective tastes differ greatly as the recent controversial
"singleton" proposal showed, and even though reexporting `on` from Prelude
has an objective merit in contrast, and I can definitely sympathise with
*this* proposal, I'm not sure if we really need to modify `base` to
achieve the stated goal of having a more convenient function in scope.
But to be clear; at this point, I'm neither for nor against the proposal to
reexport names from Data.Function from the `base` Prelude.
On Wed, Sep 11, 2019 at 1:32 PM Dmitrii Kovanikov
+1 from me
We export `on` from `relude` by default and didn't have any problems so far:
* http://hackage.haskell.org/package/relude-0.5.0/docs/Relude-Function.html#v:...
I believe that this proposal hits the same wall like all other proposals regarding changes to the standard library — it's not clear, what are Prelude goals. Should it be minimal and provide only fundamental things, or should it enforce commonly used idioms? I think that the `on` function from this proposal is the most widely used version of any other function with the same name. When I see `on` in the code, I first expect the version from `base`, not from some external library with a different type. Implementing your own `on` in your library and forcing users to use it makes code hard to read and reason about. Especially when people are using implicit imports — good luck figuring out which one `on` is used! I believe that if `on` was already imported by `Prelude`, fewer people would introduce identifiers with this name. Which means that exporting `on` from `Prelude` is an excellent thing to do if `Prelude` wants to force idiomatic usage of this function.
On Wed, Sep 11, 2019 at 1:53 AM David Feuer
wrote: Every time I reach for Data.Function.on, I feel like a total dolt for having to import a module to get a function whose implementation is barely longer than the import. And it's a really good function too! Can we please add it to the Prelude?
on :: (b -> b -> c) -> (a -> b) -> a -> a -> c (.*.) `on` f = \x y -> f x .*. f y _______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
_______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries

Perhaps this question should be answered: What is the guiding principle for
Prelude? Why does it exist?
This is probably the most contentious module in all of Haskell's ecosystem.
Everyone wants to vie for their definition of "idiomatic" and getting
something into Prelude is how you "win". But we all already have things in
Prelude we don't like... Like head... How did that get in there? I'm sure
many of us would love to go back and remove it. But once something is in
Prelude it's "idiomatic" so becomes extremely hard to remove.
So, What guides Prelude? Why does Prelude exist?
If there's an answer to that in the report or something, I sense it would
make these discussions so much simpler. If there is no answer then there is
no metric by which to judge any comment in this thread.
On Wed, Sep 11, 2019, 7:53 AM Herbert Valerio Riedel
Hello everyone,
To provide another data-point; in my "Prelude module replacement" package
http://hackage.haskell.org/package/Prelude
which encodes a common standard vocabulary from `base` I've observed in my own projects over the years where I often keep a "local prelude" module for the purpose of establishing a project-specific common vocabulary. Under these constraints, `on` as well as `&` happens to be such a common vocabulary which I expect to have in my default scope, and thus is reexported from the "Prelude" module:
http://hackage.haskell.org/package/Prelude-0.1.0.1/docs/Prelude.html#g:21
But then again, since it's so easy to implement your own opinionated "Prelude" replacement (either project-local or as a package on Hackage), and subjective tastes differ greatly as the recent controversial "singleton" proposal showed, and even though reexporting `on` from Prelude has an objective merit in contrast, and I can definitely sympathise with *this* proposal, I'm not sure if we really need to modify `base` to achieve the stated goal of having a more convenient function in scope.
But to be clear; at this point, I'm neither for nor against the proposal to reexport names from Data.Function from the `base` Prelude.
On Wed, Sep 11, 2019 at 1:32 PM Dmitrii Kovanikov
wrote: +1 from me
We export `on` from `relude` by default and didn't have any problems so far:
* http://hackage.haskell.org/package/relude-0.5.0/docs/Relude-Function.html#v:...
I believe that this proposal hits the same wall like all other proposals regarding changes to the standard library — it's not clear, what are Prelude goals. Should it be minimal and provide only fundamental things, or should it enforce commonly used idioms? I think that the `on` function from this proposal is the most widely used version of any other function with the same name. When I see `on` in the code, I first expect the version from `base`, not from some external library with a different type. Implementing your own `on` in your library and forcing users to use it makes code hard to read and reason about. Especially when people are using implicit imports — good luck figuring out which one `on` is used! I believe that if `on` was already imported by `Prelude`, fewer people would introduce identifiers with this name. Which means that exporting `on` from `Prelude` is an excellent thing to do if `Prelude` wants to force idiomatic usage of this function.
On Wed, Sep 11, 2019 at 1:53 AM David Feuer
wrote: Every time I reach for Data.Function.on, I feel like a total dolt for having to import a module to get a function whose implementation is barely longer than the import. And it's a really good function too! Can we please add it to the Prelude?
on :: (b -> b -> c) -> (a -> b) -> a -> a -> c (.*.) `on` f = \x y -> f x .*. f y _______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
_______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
_______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries

-1 from me; I have no problem with long import lists as I'd prefer to know
_where_ a function comes from than keeping track of "what's in Prelude this
month?" (looking at you random Monoid, Semigroup, etc. additions to
Prelude).
I use `on` a _lot_ and have never once considered doing a custom Prelude or
anything like that.
On Wed, 11 Sep. 2019, 9:00 pm Elliot Cameron,
Perhaps this question should be answered: What is the guiding principle for Prelude? Why does it exist?
This is probably the most contentious module in all of Haskell's ecosystem. Everyone wants to vie for their definition of "idiomatic" and getting something into Prelude is how you "win". But we all already have things in Prelude we don't like... Like head... How did that get in there? I'm sure many of us would love to go back and remove it. But once something is in Prelude it's "idiomatic" so becomes extremely hard to remove.
So, What guides Prelude? Why does Prelude exist?
If there's an answer to that in the report or something, I sense it would make these discussions so much simpler. If there is no answer then there is no metric by which to judge any comment in this thread.
On Wed, Sep 11, 2019, 7:53 AM Herbert Valerio Riedel
wrote: Hello everyone,
To provide another data-point; in my "Prelude module replacement" package
http://hackage.haskell.org/package/Prelude
which encodes a common standard vocabulary from `base` I've observed in my own projects over the years where I often keep a "local prelude" module for the purpose of establishing a project-specific common vocabulary. Under these constraints, `on` as well as `&` happens to be such a common vocabulary which I expect to have in my default scope, and thus is reexported from the "Prelude" module:
http://hackage.haskell.org/package/Prelude-0.1.0.1/docs/Prelude.html#g:21
But then again, since it's so easy to implement your own opinionated "Prelude" replacement (either project-local or as a package on Hackage), and subjective tastes differ greatly as the recent controversial "singleton" proposal showed, and even though reexporting `on` from Prelude has an objective merit in contrast, and I can definitely sympathise with *this* proposal, I'm not sure if we really need to modify `base` to achieve the stated goal of having a more convenient function in scope.
But to be clear; at this point, I'm neither for nor against the proposal to reexport names from Data.Function from the `base` Prelude.
On Wed, Sep 11, 2019 at 1:32 PM Dmitrii Kovanikov
wrote: +1 from me
We export `on` from `relude` by default and didn't have any problems so far:
* http://hackage.haskell.org/package/relude-0.5.0/docs/Relude-Function.html#v:...
I believe that this proposal hits the same wall like all other proposals regarding changes to the standard library — it's not clear, what are Prelude goals. Should it be minimal and provide only fundamental things, or should it enforce commonly used idioms? I think that the `on` function from this proposal is the most widely used version of any other function with the same name. When I see `on` in the code, I first expect the version from `base`, not from some external library with a different type. Implementing your own `on` in your library and forcing users to use it makes code hard to read and reason about. Especially when people are using implicit imports — good luck figuring out which one `on` is used! I believe that if `on` was already imported by `Prelude`, fewer people would introduce identifiers with this name. Which means that exporting `on` from `Prelude` is an excellent thing to do if `Prelude` wants to force idiomatic usage of this function.
On Wed, Sep 11, 2019 at 1:53 AM David Feuer
wrote: Every time I reach for Data.Function.on, I feel like a total dolt for having to import a module to get a function whose implementation is barely longer than the import. And it's a really good function too! Can we please add it to the Prelude?
on :: (b -> b -> c) -> (a -> b) -> a -> a -> c (.*.) `on` f = \x y -> f x .*. f y _______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
_______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
_______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
_______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries

-1, for the same reasons as Ivan.
I would prefer *everything* to have an explicit import "binding site",
and I'd also rather that not be a huge single line from one module
(though of course, I can break the import up other multiple lines).
On Wed, Sep 11, 2019 at 3:11 PM Ivan Lazar Miljenovic
-1 from me; I have no problem with long import lists as I'd prefer to know _where_ a function comes from than keeping track of "what's in Prelude this month?" (looking at you random Monoid, Semigroup, etc. additions to Prelude).
I use `on` a _lot_ and have never once considered doing a custom Prelude or anything like that.
On Wed, 11 Sep. 2019, 9:00 pm Elliot Cameron,
wrote: Perhaps this question should be answered: What is the guiding principle for Prelude? Why does it exist?
This is probably the most contentious module in all of Haskell's ecosystem. Everyone wants to vie for their definition of "idiomatic" and getting something into Prelude is how you "win". But we all already have things in Prelude we don't like... Like head... How did that get in there? I'm sure many of us would love to go back and remove it. But once something is in Prelude it's "idiomatic" so becomes extremely hard to remove.
So, What guides Prelude? Why does Prelude exist?
If there's an answer to that in the report or something, I sense it would make these discussions so much simpler. If there is no answer then there is no metric by which to judge any comment in this thread.
On Wed, Sep 11, 2019, 7:53 AM Herbert Valerio Riedel
wrote: Hello everyone,
To provide another data-point; in my "Prelude module replacement" package
http://hackage.haskell.org/package/Prelude
which encodes a common standard vocabulary from `base` I've observed in my own projects over the years where I often keep a "local prelude" module for the purpose of establishing a project-specific common vocabulary. Under these constraints, `on` as well as `&` happens to be such a common vocabulary which I expect to have in my default scope, and thus is reexported from the "Prelude" module:
http://hackage.haskell.org/package/Prelude-0.1.0.1/docs/Prelude.html#g:21
But then again, since it's so easy to implement your own opinionated "Prelude" replacement (either project-local or as a package on Hackage), and subjective tastes differ greatly as the recent controversial "singleton" proposal showed, and even though reexporting `on` from Prelude has an objective merit in contrast, and I can definitely sympathise with *this* proposal, I'm not sure if we really need to modify `base` to achieve the stated goal of having a more convenient function in scope.
But to be clear; at this point, I'm neither for nor against the proposal to reexport names from Data.Function from the `base` Prelude.
On Wed, Sep 11, 2019 at 1:32 PM Dmitrii Kovanikov
wrote: +1 from me
We export `on` from `relude` by default and didn't have any problems so far:
* http://hackage.haskell.org/package/relude-0.5.0/docs/Relude-Function.html#v:...
I believe that this proposal hits the same wall like all other proposals regarding changes to the standard library — it's not clear, what are Prelude goals. Should it be minimal and provide only fundamental things, or should it enforce commonly used idioms? I think that the `on` function from this proposal is the most widely used version of any other function with the same name. When I see `on` in the code, I first expect the version from `base`, not from some external library with a different type. Implementing your own `on` in your library and forcing users to use it makes code hard to read and reason about. Especially when people are using implicit imports — good luck figuring out which one `on` is used! I believe that if `on` was already imported by `Prelude`, fewer people would introduce identifiers with this name. Which means that exporting `on` from `Prelude` is an excellent thing to do if `Prelude` wants to force idiomatic usage of this function.
On Wed, Sep 11, 2019 at 1:53 AM David Feuer
wrote: Every time I reach for Data.Function.on, I feel like a total dolt for having to import a module to get a function whose implementation is barely longer than the import. And it's a really good function too! Can we please add it to the Prelude?
on :: (b -> b -> c) -> (a -> b) -> a -> a -> c (.*.) `on` f = \x y -> f x .*. f y _______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
_______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
_______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
_______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
_______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries

What do you mean by "I'd also rather that not be a huge single line from one module"? Can you elaborate how this relates to the proposal? Am Mi., 11. Sept. 2019 um 14:45 Uhr schrieb Oliver Charles < ollie@ocharles.org.uk>:
I would prefer *everything* to have an explicit import "binding site", and I'd also rather that not be a huge single line from one module (though of course, I can break the import up other multiple lines).

I would ignore that comment actually, it's not well thought out.
(I was roughly meaning that I don't want to write `import Prelude (x1,
x2, ..., x500)`, but this isn't a valid argument as I don't actually
explicitly import `Prelude` anyway).
That said, I would still prefer as many symbols as possible to have
explicit binding sites, which means I would prefer to be explicit
about my import to `on` rather than assume it from the Prelude.
On Wed, Sep 11, 2019 at 3:49 PM Helmut Schmidt
What do you mean by "I'd also rather that not be a huge single line from one module"? Can you elaborate how this relates to the proposal?
Am Mi., 11. Sept. 2019 um 14:45 Uhr schrieb Oliver Charles
: I would prefer *everything* to have an explicit import "binding site", and I'd also rather that not be a huge single line from one module (though of course, I can break the import up other multiple lines).

On Wed, Sep 11, 2019 at 5:21 PM Oliver Charles
That said, I would still prefer as many symbols as possible to have explicit binding sites, which means I would prefer to be explicit about my import to `on` rather than assume it from the Prelude.
I personally share this preference. In my own code, I enable NoImplicitPrelude and explicitly import symbols from whatever module is the logical home for any given symbol. As I have this personal preference, I would explicitly `import Data.Function (on)` as I do today, irrespective of the outcome of this proposal. This is generally possible for any symbol that is not actually defined in the Prelude but merely re-exported from somewhere else. I mean to say that this particular style neither benefits nor is impaired much by this proposal. There would still be a Prelude with lots of symbols, and you will still be able to pretend there isn't one to the benefit of explicit binding sites, to whichever degree you personally favour.

On Wed, Sep 11, 2019 at 7:11 AM Ivan Lazar Miljenovic
-1 from me; I have no problem with long import lists as I'd prefer to know _where_ a function comes from than keeping track of "what's in Prelude this month?" (looking at you random Monoid, Semigroup, etc. additions to Prelude).
I use `on` a _lot_ and have never once considered doing a custom Prelude or anything like that.
I solved the "not in prelude" problem for myself long ago by writing a tool to manage imports. So I either use a local "prelude addition" module, or I configure the tool with the set of things I'd like to be in scope unqualified and it makes sure they're imported if they're used. Not that I expect everyone to use such a tool, but just that there are a few ways to solve the problem. When the Prelude changes it becomes especially easy to break compatibility with a previous ghc version. Even if you have CI running with previous ghcs, the notification is very late. I suppose hlint could probably be configured to warn in advance though. To this day I still have lots of "unused import" warnings due to (<>) that I can't get rid of without either tons of CPP or dropping compatibility for whatever version it was that put it in prelude (though I think Monoid was worth it!).

On Tue, 10 Sep 2019, David Feuer wrote:
Every time I reach for Data.Function.on, I feel like a total dolt for having to import a module to get a function whose implementation is barely longer than the import. And it's a really good function too! Can we please add it to the Prelude? on :: (b -> b -> c) -> (a -> b) -> a -> a -> c (.*.) `on` f = \x y -> f x .*. f y
Most of the time I would use this I can use the more specific 'equating' and 'comparing'. I remember there was a lengthy discussion about the right name of 'on' and adding it to Data.Function. I had no need for that function because at this point I already had: https://hackage.haskell.org/package/utility-ht-0.0.14/docs/Data-Function-HT.... If I am right the short name 'on' was only adopted because it was not (automatically) exported by Prelude.

It's not only about top-level functions named 'on'. If I use 'on' as a local variable, then I get warnings about local redefinitions of the global Prelude.on.
Oh heavens how did we not think of this point immediately? This frankly has me terrified of this proposal. This is such a cute name it's hard to imagine that it's not a local binding in numerous, invisible places. (Just last week I had to fix a package not on Hackage because it locally defined (<>)...) On Fri, Sep 13, 2019, 7:54 AM Henning Thielemann < lemming@henning-thielemann.de> wrote:
On Tue, 10 Sep 2019, David Feuer wrote:
Every time I reach for Data.Function.on, I feel like a total dolt for having to import a module to get a function whose implementation is barely longer than the import. And it's a really good function too! Can we please add it to the Prelude? on :: (b -> b -> c) -> (a -> b) -> a -> a -> c (.*.) `on` f = \x y -> f x .*. f y
Most of the time I would use this I can use the more specific 'equating' and 'comparing'.
I remember there was a lengthy discussion about the right name of 'on' and adding it to Data.Function. I had no need for that function because at this point I already had:
https://hackage.haskell.org/package/utility-ht-0.0.14/docs/Data-Function-HT....
If I am right the short name 'on' was only adopted because it was not (automatically) exported by Prelude._______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries

yeah, that pushes it to a hard -1 for me.
On Fri, Sep 13, 2019 at 9:33 AM Elliot Cameron
It's not only about top-level functions named 'on'. If I use 'on' as a local variable, then I get warnings about local redefinitions of the global Prelude.on.
Oh heavens how did we not think of this point immediately? This frankly has me terrified of this proposal. This is such a cute name it's hard to imagine that it's not a local binding in numerous, invisible places.
(Just last week I had to fix a package not on Hackage because it locally defined (<>)...)
On Fri, Sep 13, 2019, 7:54 AM Henning Thielemann < lemming@henning-thielemann.de> wrote:
On Tue, 10 Sep 2019, David Feuer wrote:
Every time I reach for Data.Function.on, I feel like a total dolt for having to import a module to get a function whose implementation is barely longer than the import. And it's a really good function too! Can we please add it to the Prelude? on :: (b -> b -> c) -> (a -> b) -> a -> a -> c (.*.) `on` f = \x y -> f x .*. f y
Most of the time I would use this I can use the more specific 'equating' and 'comparing'.
I remember there was a lengthy discussion about the right name of 'on' and adding it to Data.Function. I had no need for that function because at this point I already had:
https://hackage.haskell.org/package/utility-ht-0.0.14/docs/Data-Function-HT....
If I am right the short name 'on' was only adopted because it was not (automatically) exported by Prelude._______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
_______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries

On Fri, 13 Sep 2019 at 13:54, Henning Thielemann < lemming@henning-thielemann.de> wrote:
On Tue, 10 Sep 2019, David Feuer wrote:
Every time I reach for Data.Function.on, I feel like a total dolt for having to import a module to get a function whose implementation is barely longer than the import. And it's a really good function too! Can we please add it to the Prelude? on :: (b -> b -> c) -> (a -> b) -> a -> a -> c (.*.) `on` f = \x y -> f x .*. f y
Most of the time I would use this I can use the more specific 'equating' and 'comparing'.
Does 'equating' exist in base now? I've always missed having that function in the past, and defined it myself many times. Erik

I consider equating (and comparing) a bit of an anti-pattern. They're extra
names to express what `on` does more generally, and barely save any
characters over it
On Sat, Sep 14, 2019, 2:51 PM Erik Hesselink
On Fri, 13 Sep 2019 at 13:54, Henning Thielemann < lemming@henning-thielemann.de> wrote:
On Tue, 10 Sep 2019, David Feuer wrote:
Every time I reach for Data.Function.on, I feel like a total dolt for having to import a module to get a function whose implementation is barely longer than the import. And it's a really good function too! Can we please add it to the Prelude? on :: (b -> b -> c) -> (a -> b) -> a -> a -> c (.*.) `on` f = \x y -> f x .*. f y
Most of the time I would use this I can use the more specific 'equating' and 'comparing'.
Does 'equating' exist in base now? I've always missed having that function in the past, and defined it myself many times.
Erik

-1
I find `on` rather handy, but I would prefer that Prelude not claim so
many identifiers, especially short ones like this.
On Sun, 15 Sep 2019 at 12:18, David Feuer
I consider equating (and comparing) a bit of an anti-pattern. They're extra names to express what `on` does more generally, and barely save any characters over it
On Sat, Sep 14, 2019, 2:51 PM Erik Hesselink
wrote: On Fri, 13 Sep 2019 at 13:54, Henning Thielemann
wrote: On Tue, 10 Sep 2019, David Feuer wrote:
Every time I reach for Data.Function.on, I feel like a total dolt for having to import a module to get a function whose implementation is barely longer than the import. And it's a really good function too! Can we please add it to the Prelude? on :: (b -> b -> c) -> (a -> b) -> a -> a -> c (.*.) `on` f = \x y -> f x .*. f y
Most of the time I would use this I can use the more specific 'equating' and 'comparing'.
Does 'equating' exist in base now? I've always missed having that function in the past, and defined it myself many times.
Erik
_______________________________________________ Libraries mailing list Libraries@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
participants (18)
-
Andreas Abel
-
Artyom Kazak
-
Carter Schonwald
-
chessai .
-
David Feuer
-
Dmitrii Kovanikov
-
Edward Kmett
-
Elliot Cameron
-
Erik Hesselink
-
Evan Laforge
-
George Wilson
-
Helmut Schmidt
-
Henning Thielemann
-
Herbert Valerio Riedel
-
Ivan Lazar Miljenovic
-
Manuel Gómez
-
Oliver Charles
-
Ryan Trinkle