Visitar URL original
Proposal: Rename `Foldable1` and `Bifoldable1` and then move them into base · Issue #9 · haskell/core-libraries-committee · GitHub
Skip to content

Proposal: Rename Foldable1 and Bifoldable1 and then move them into base #9

Closed

Description

@gwils

I propose that we move Foldable1 and Bifoldable1 from semigroupoids to base, as has been discussed many times over the years, and has most recently been championed by @phadej. His write-up found here contains a large collection of useful links to context and prior discussion. I invite you to read that; I couldn't possibly summarise all the discussion here.

Before we move these classes to base, I propose that we get their names right, along the lines discussed by @chessai and others on this semigroupoids issue (Foldable1 -> Semifoldable, Bifoldable1 -> Semibifoldable, with matching renamings for class members).

Hence this proposal involves multiple steps:

  1. Release version 6.0.0 of semigroupoids with a mass-renaming (Foldable1 to Semifoldable, Bifoldable1 to Semibifoldable, etc.)
  2. Update downstream packages of semigroupoids to use the new major version and hence the naming scheme.
  3. Let the ecosystem settle for a while.
  4. Move Semifoldable and Semibifoldable to base.

We could alternatively do the renaming and relocation as one step, but this approach leads to a rather unfortunate migration path for users. I would prefer they be two simple and discrete steps, giving the considerable downstream package ecosystem time to breathe in between.

This proposal an additive (non-breaking) change to base, and so that step is relatively easy. Moving other classes from semigroupoids to base is explicitly out of scope for this proposal. Most or all other classes (such as Semitraversable) require breaking changes elsewhere in the hierarchy (such as wedging Semiapplicative into the Monad hierarchy).

I note that this is as much a proposal about semigroupoids as it is about base; hence we would need the support of the semigroupoids maintainers(cc. @ekmett).

Activity

  1. phadej commented on Oct 30, 2021

    @phadej

    I still think that Foldable1 (or whichever name it's renamed to) should be moved out of semigroupoids into own package (Bifoldable1 can be there on in bifunctors), as semigroupoids is just too dependency heavy as used as compatibility package. People don't want to depend on it. If semigroupoids is used as a compat package, the adoption may be abysmal. (I know an example where a maintainer didn't want to depend on semigroups, and Semigroup instances were added only when the support for older GHCs were dropped to avoid non-uniform APIs).

    I.e. First move & rename functionality into own package (like https://github.com/phadej/foldable1), then make semigroupoids depend on it (like in ekmett/semigroupoids#87).

    I don't see a need to wait for ecosystem to settle Foldable1 is defined in handful of packages: instance.*Foldable1 search shows 50 packages https://hackage-search.serokell.io/?q=instance.*Foldable1 (also good part is Edwards packages) I.e. if change is done today to semigroupoids, the next base (released in 6 months?) could well have Foldable1 in it.

  2. Bodigrim commented on Oct 30, 2021

    @Bodigrim
    Contributor

    I like @phadej's suggestion to factor out Foldable1 into a package on its own. Otherwise future packages, using Foldable1 from base, will be forced either support only GHC 9.4+, or depend on relatively heavyweight semigroupoids.

  3. Bodigrim commented on Oct 30, 2021

    @Bodigrim
    Contributor

    CC @ekmett @RyanGlScott on behalf of semigroupoids.

    I think it could help to split this task into three:

    1. Does CLC approve inclusion of Foldable1 into base in principle?
    2. If yes, is CLC in favor of renaming to Semifoldable?
    3. If yes, which migration plan is recommended by CLC?

    Dear CLC members, could you please answer questions 1 and 2, before we venture on bikeshedding 3?

  4. gwils commented on Oct 31, 2021

    @gwils
    ContributorAuthor

    As you'd expect, I'm yes on 1 and 2.

  5. Bodigrim commented on Oct 31, 2021

    @Bodigrim
    Contributor
    1. Yes.
    2. I'm slightly more inclined to keep current naming to simplify migration. While Semifoldable sounds great, semimaximum and semilast are horrible.

    CC @emilypi @chessai @cgibbard @cigsender

  6. phadej commented on Oct 31, 2021

    @phadej

    I'm slightly more inclined to keep current naming to simplify migration. While Semifoldable sounds great, semimaximum and semilast are horrible.

    My proposal had different naming schemes. NonEmptyFoldable naming scheme is not horrible. And doesn't try to make Semi prefix to mean non empty. EDIT: semi means "not completely: semigroup is almost group, no inverse so no identity; semimaximum doesn't make sense; semifoldr more, as that's a foldr without initial element; semifoldrMap is questionable, foldrMap1 means "map 1, foldr rest" :)

    Another

    head, maximum and foldr1 already exist in base.
    These are good names, but they are partial. So there is argument

    • for some methods and functions to be named even without an affix, i.e. have good names for the right things.
    • or against, as that would cause name clashes (yet, people using Foldable1 probably won't use maximum from Foldable or head from Data.List; but these are Prelude names, so inconvenience is present).
  7. Bodigrim commented on Oct 31, 2021

    @Bodigrim
    Contributor

    Hmm. Using unprefixed head, last, maximum and minimum for Semifoldable could be a bold, but long-awaited move to pave an (extremely long-term) migration from partial Prelude.

  8. mixphix commented on Oct 31, 2021

    @mixphix
    Contributor

    I'm yes on 1, no on 2. I think the *1 suffix is fine on the class name, but that we should clash with the Prelude on the function names. I agree with @Bodigrim that it will steer us in the right direction when the time comes to de-partialize the Prelude.

  9. ocramz commented on Nov 6, 2021

    @ocramz

    FWIW (not a CLC member) :

    • moving Foldable1 to base is a great idea , +1
    • renaming it to SemiFoldable (or NonEmptyFoldable, even better as @phadej suggests ) : +1 , because currently there are classes like Show1 and Eq1 in base for * -> * types (and Generic1 will land soon afaik). I'm concerned this overloaded meaning of 1 would cause confusion.

    Hmm. Using unprefixed head, last, maximum and minimum for Semifoldable could be a bold, but long-awaited move to pave an (extremely long-term) migration from partial Prelude.

    @Bodigrim this is a great suggestion and I'm sure would be well received.

  10. szabi commented on Nov 6, 2021

    @szabi

    Hmm. Using unprefixed head, last, maximum and minimum for Semifoldable could be a bold, but long-awaited move to pave an (extremely long-term) migration from partial Prelude.

    (Not a CLC member): I think this argument (re naming schemes) should be considered as particularly important.

    I'd also consider Semi- as way to jargon-y without actually having good precedent for it. Current Foldable1 seems fine; NonEmptyFoldable seems ok, but nonEmpty- for the class functions seems unergonomically verbose.

    So, I feel like it would be Foldable1 or NonEmptyFoldable for me, and unprefixed functions, at the current state of the discussion.

    These are the two cents of a bystander.

  11. chshersh commented on Nov 6, 2021

    @chshersh
    Member

    (Not a CLC member)

    I'd love to see typeclasses Foldable1 in base. I'm -1 on renaming them. I don't think that renaming solves any problem. It'll introduce even more work for volunteers to migrate their packages and I don't get the reasons for asking people to do more work because new names somehow make more sense. They don't to me and I think that Foldable1 is already perfectly fine.

    Regarding Eq1 and Show1 typeclasses: we now have QuantifiedConstraints in GHC and those classes can be safely deprecated. So there's no need to continue this naming convention with the meaning "typeclasses for higher-kinded data types".

  12. ocramz commented on Nov 6, 2021

    @ocramz

    Let's not forget that there are multiple "user personas" involved here:

    • people who have never used Foldable1 or semigroupoids : Perhaps they would start using folds over non-empty data once it's in base but they don't face breaking change.
    • authors who are currently relying on semigroupoids: they would be impacted by a renaming of Foldable1.
    • all the work around Generic: like it or not, Show1, Eq1 and Generic1 have been in base for a while and many libraries rely upon them. While we can argue that the 1 is not a suggestive naming choice, it's become canon by now.

    Questions :

    • is the deprecation of Show1, Eq1 "a thing"? What's the timeline and/or process for deprecating them ? I cannot wrap my head around this use of QuantifiedConstraints.
    • Generic1 and Generically have recently landed in base (https://gitlab.haskell.org/ghc/ghc/-/merge_requests/5726/diffs), should they be renamed too?
  13. phadej commented on Nov 6, 2021

    @phadej

    is the deprecation of Show1, Eq1 "a thing"?

    It's not that simple. In particular Eq1 f is strictly more powerful than forall a. Eq a => Eq (f a). We can do

    applesAndOranges :: :: [Apple] -> [Orange] -> Bool
    applesAndOranges = liftEq appleAndOrange where
      appleAndOrange :: Apple -> Orange -> Bool
      appleAndOrange = ...

    i.e. compare containers of different values.

    Similarly liftShowsPrec would allow to show Set Apple using canonical instance Set showing function, but let the user supply how to show an Apple. (I use Set as an example because you cannot coerce whole Set Apple to Set MyApple, and have a Show MyApple instance you'd like).

    So Eq1/Show1/... add expressive power & vocabulary.

    What will probably happen is that QuantifiedConstraints will become a constraints of Eq1, Show1 etc.:

    class (forall a. Eq a => Eq (f a)) => Eq1 f where
      liftEq :: (a -> b -> Bool) -> (f a -> f b -> Bool)

    The effect is that instead of eq1 :: (Eq1 f, Eq a) => f a -> f a -> Bool you could directly use ==, as Eq1 f, Eq a constraints will imply Eq (f a).

    There is a Merge Request !4727, but it's currently a draft. I guess the change there will eventually be brought up to CLC.


    Generic1 has been in base essentially forever now. Since GHC-7.4 / base-4.6. Renaming it would break quite a lot of code.

    I don't see anything wrong with Generically name.

  14. ekmett commented on Nov 6, 2021

    @ekmett
    Member

    I'm happy to go with whatever the CLC wants to do here, up to and including handing the package over to the CLC.

  15. cgibbard commented on Nov 10, 2021

    @cgibbard
    Contributor

    Naming issue aside, after looking into this a bit, I'm still pretty unclear why these classes can't just keep living in semigroupoids. I guess I've never yet had to use them in anger, so they still seem pretty rarely-occurring to me... but maybe I'm just not aware of what kinds of code people are writing these days outside of my own bubbles.

    I wonder what the ratio of packages transitively depending on semigroupoids due to the need to write Foldable1/Bifoldable1 instances vs. all packages transitively depending on semigroupoids is. That is to say, how much would the transitive dependency set of semigroupoids be reduced if these classes got moved into base?

    At least in my case, while I've never really touched these classes, semigroupoids is almost always in my transitive dependency set on any medium to large project already, so depending on it once more never seems very painful.

    Also, if it's really the case that separating these classes out would help, perhaps another answer that wouldn't require the blessing of the CLC at all would just be to split the package (as insufferable as it is to suggest a tiny package like that).

  16. 88 remaining items

  17. chshersh commented on Mar 15, 2023

    @chshersh
    Member

    I'm trying to summarise the state of this proposal as part of my volunteering effort to track the progress of all approved CLC proposals.

    Field Value
    Author @gwils, @Bodigrim
    Status merged
    base version 4.18.0.0
    Merge Request (MR) https://gitlab.haskell.org/ghc/ghc/-/merge_requests/8495
    Blocked by nothing
    CHANGELOG entry present
    Migration guide not needed

    Please, let me know if you find any mistakes 🙂

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    approvedApproved by CLC votebase-4.18Implemented in base-4.18 (GHC 9.6)

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions