<div><div dir="auto">I think I follow.  </div></div><div dir="auto"><br></div><div dir="auto">Pedantic point : when you say semantics, it might be less confusing and more precise to performance tradeoffs. </div><div dir="auto"><br></div><div dir="auto">My English language and naive preference is to assume *With functions grammar better.  Or *by. I think the *on idiom is younger relatively.  </div><div dir="auto"><br></div><div dir="auto">Can I challenge you to reflect on what challenge  you are trying to address with this proposal and if there’s a course of action that you feel improves everything but breaks no code ?  And what would make the change an improvement for software using these modules already </div><div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Sat, Feb 15, 2020 at 7:36 AM Philip Hazelden <<a href="mailto:philip.hazelden@gmail.com">philip.hazelden@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div dir="ltr"><div>Hi,</div><div><br></div><div>> clc gets / reads libraries anyways, no need to double email : )<br></div><div><br></div><div>Fair enough. I tried to follow the process suggested at <a href="https://wiki.haskell.org/Core_Libraries_Committee" target="_blank">https://wiki.haskell.org/Core_Libraries_Committee</a> by emailing both lists. I was surprised that the mail to libraries@ got rejected. No big deal, but should that page be updated?</div><div><br></div><div>> are we talking about the specifics of the implementations while stilling having the same observable pure results, OR something different?</div><div dir="ltr"><br></div><div>For sortWith/sortOn, yeah, my proposal #3 would change performance characteristics but not the pure semantics.</div><div dir="ltr"><br></div><div dir="ltr">The existing functions that we have are<br><br>    Data.List.sortOn f =<br>      map snd . sortBy (comparing fst) . map (\x -> let y = f x in y `seq` (y, x))<br>    GHC.Exts.sortWith f = sortBy (\x y -> compare (f x) (f y))<br>    Data.List.NonEmpty.sortWith = sortBy . comparing<br><br>Where the first two have type signature `Ord b :: (a -> b) -> [a] -> [a]` and the last is `Ord b :: (a -> b) -> NonEmpty a -> NonEmpty a`.<br><br>Data.List.sortOn is implemented in a way that calls its projection function just once per list element, but it allocates an intermediate list. If the projection function is expensive, that'll be worth it. The style of the functions named sortWith avoids the intermediate list, but at the cost of calling the projection twice for each comparison; so that'll be better if the projection is cheap.<br><br>I bring this up because issue 12044 suggested removing `GHC.Exts.sortWith` for being semantically the same as `Data.List.sortOn`, and the performance question was brought up there. To be clear, I don't think it's a big deal.<br></div><div dir="ltr"><br></div><div dir="ltr">> please spell this out more concretely, i'm not able to decode what you mean unambiguiously. Just changing the names of some functions in base in isolation breaks code for no reason,<br></div><div dir="ltr"><br></div><div>My proposals #1 and #2 are just to change the names of functions, yeah. But it's not for no reason.</div><div><br></div><div>There are two problems with the current names. The smaller one, applying to all of these functions, is that I believe the "On" pattern is more widely used. And so if a user tries to guess what these functions will be called, they'll most likely go for that.</div><div><br></div><div>(I don't have any hard data here, admittedly. We see "On" in Data.List.sortOn, but also many functions in Data.List.Extra like `nubOn`, `groupOn`, `maximumOn`. Admittedly that's not in base. But I'll also note that NonEmpty.sortWith was originally called sortOn, and the groupWith functions were originally requested with the name groupOn; see <a href="https://github.com/ekmett/semigroups/pull/52" target="_blank">https://github.com/ekmett/semigroups/pull/52</a>. So yeah, my sense is that "On" is what most people will expect.)</div><div><br></div><div>The more significant one, applying to the group functions but not to sortWith, is that the only other function in base named `groupWith` has a comparable type signature but different semantics. Data.List.NonEmpty.groupWith is "group according to a projection function" while GHC.Exts.groupWith is "sort and group according to a projection function". If someone gets these behaviours confused, they're going to sort when they don't intend to, or to not sort when they do intend to. Using more consistent naming may help avoid that.</div><div><br></div><div>It may be that this isn't enough reason to break code. If the committee decides that it's not, then fair enough.</div><div><br></div><div>Though, it now occurs to me that renaming `GHC.Exts.groupWith` to `groupAllOn` or `groupAllWith` or something (in Data.List.Extra it's named "groupSortOn"), could also help clear up the larger problem while breaking less code. So I'll offer that possibility for consideration too.<br></div><div><br></div></div></div><div dir="ltr"><div><br></div><div><div class="gmail_quote"><div dir="ltr" class="gmail_attr"><br></div><div dir="ltr" class="gmail_attr">On Thu, Feb 13, 2020 at 10:17 PM Carter Schonwald <<a href="mailto:carter.schonwald@gmail.com" target="_blank">carter.schonwald@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr">Hello Philip, clc gets / reads libraries anyways, no need to double email : )<div><br></div><div>perhaps i'm missing something, are we talking about the specifics of the implementations while stilling having the same observable pure results, OR something different?</div><div><br></div><div>When does each have a clear performance win? </div><div><br></div><div>at least from my native english speaker perspective, sortWith is better grammar.  Are you describing a choice of performance characteristics related to  *On vs *With functions?</div><div><br></div><div>also, could you spell out which reference implementations of which convention enshrine which meanings you have in mind? </div><div><br></div><div>I dont see a good reason to change the names that are provided from one to the other. Are you merely making the case that both styles should be exported from certain places, and that a particular choice of evaluation trade offs be enshrined by the respective naming convention?</div><div><br></div><div><br></div><div>please spell this out more concretely, i'm not able to decode what you mean unambiguiously. Just changing the names of some functions in base in isolation breaks code for no reason, so if you are arguing for that, i'm gonna say nope :)  </div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Wed, Feb 12, 2020 at 12:58 PM Philip Hazelden <<a href="mailto:philip.hazelden@gmail.com" target="_blank">philip.hazelden@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div>Hi,</div><div><br></div><div>I'm referring to these functions: `sortWith` `groupWith` `groupAllWith` `groupWith1` `groupAllWith1`.<br></div><br>The `On` suffix is more common for such things, and I anticipate it's what most users will normally expect them to be named.<br><br>Additionally, the name `groupWith` is potentially misleading. That name is also used in GHC.Exts[1], for a function with the same type signature but different semantics. `GHC.Exts.groupWith` sorts its input list, unlike `NonEmpty.groupWith` or `Data.List.Extra.groupOn`. (In NonEmpty, we have `groupAllWith` for group-with-sort. So we have three names, two semantics, and no consistency.)<br><br>According to <a href="https://github.com/ekmett/semigroups/pull/52" target="_blank">https://github.com/ekmett/semigroups/pull/52</a>, `With` was chosen because:<br><br>> The preferred vocabulary for On here is With to match the combinators in GHC.Exts from the "comprehensive comprehensions" paper. That'd make it so that if you use these with comprehensive comprehensions turned on and RebindableSyntax turned on then you'd get these combinators.<br><br>But I don't see anything in the docs which suggests that the TransformListComp extension[2] uses these functions implicitly, or interacts with RebindableSyntax[3]. So perhaps I'm missing something, but my guess is this is no longer a concern.<br><br>The case for `sortWith` is weaker, since it might trip people up but it won't introduce unexpected semantics. There's also a counter argument in <a href="https://gitlab.haskell.org/ghc/ghc/issues/12044" target="_blank">https://gitlab.haskell.org/ghc/ghc/issues/12044</a>. `Data.List.sortOn` only computes the mapping function once for each element, while `GHC.Exts.sortWith` computes it every time it does a comparison but uses fewer allocations. `Data.NonEmpty.sortWith` acts like the latter. My suggestion would be to replace it with a `sortOn` implemented like `Data.List.sortOn`, but I also don't think it would be terrible to have both, or even to just rename and leave this small inconsistency. If there's no agreement on this function, I think it would be worth renaming the group functions anyway.<br><br>And so I propose, in descending order of how much I care:<br><br>1. Rename the group functions to be named "On" instead of "With".<div><br><div>2. Rename `sortWith` to `sortOn` In the case of `sortWith`, also reimplement it as<br><br>3. Reimplement `sortOn` as</div><div><br>    sortOn :: Ord b => (a -> b) -> NonEmpty a -> NonEmpty a<br>    sortOn = fmap snd . sortBy (comparing fst) . fmap (\x -> let y = f x in y `seq` (y, x))<br><br>I assume the process here would be to leave the existing names for a time with deprecation warnings, and then remove them a few versions down the line.<br><div><br></div><div>[1] <a href="https://hackage.haskell.org/package/base-4.12.0.0/docs/GHC-Exts.html#v:groupWith" target="_blank">https://hackage.haskell.org/package/base-4.12.0.0/docs/GHC-Exts.html#v:groupWith</a><br></div><div>[2] <a href="https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/glasgow_exts.html#extension-TransformListComp" target="_blank">https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/glasgow_exts.html#extension-TransformListComp</a></div><div>[3] <a href="https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/glasgow_exts.html#extension-RebindableSyntax" target="_blank">https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/glasgow_exts.html#extension-RebindableSyntax</a></div></div></div><div><br></div><div>Best,</div><div>Phil</div></div>

<p></p>

-- <br>
You received this message because you are subscribed to the Google Groups "haskell-core-libraries" group.<br>
To unsubscribe from this group and stop receiving emails from it, send an email to <a href="mailto:haskell-core-libraries+unsubscribe@googlegroups.com" target="_blank">haskell-core-libraries+unsubscribe@googlegroups.com</a>.<br>
To view this discussion on the web visit <a href="https://groups.google.com/d/msgid/haskell-core-libraries/CALB5dS-5qKjK6rmvFg2TuZ_3HvPtPyuGzsTrVO8adAnX1zovdg%40mail.gmail.com?utm_medium=email&utm_source=footer" target="_blank">https://groups.google.com/d/msgid/haskell-core-libraries/CALB5dS-5qKjK6rmvFg2TuZ_3HvPtPyuGzsTrVO8adAnX1zovdg%40mail.gmail.com</a>.<br>
</blockquote></div>
</blockquote></div></div></div>
</blockquote></div></div>