Monad of No Return: The Great Patchening

Hi all!

tl;dr: I have 148 packages on stackage to patch for compatibility, and I’d like your help!

I’ve got another update on the Monad of No Return/Monoid of No Mappend proposal.

Following proposal acceptance just under a year ago, I started implementation this year. Recently the MR is in a good enough state for me to check it against clc-stackage, a tool for building all of stackage against custom GHC versions.

The result of that is this issue in the core library committee repository, where I detail which packages have changes which need to be put on to hackage, as well as a huge, unreadable gist filled with patches I made to get stackage compiling.

That brings me to the point of this discourse post - I ask that anyone that has a moment peruse the list, and if you are a contributor to one of these packages (or want to get involved with a package), that you submit a patch and let me know!

There are a lot of packages to patch, each with their own history and customs, and it would save time in the long run if patches are made that suit each package.

As well as the explicit breakage (of non-canonical pure, return, (<>), and mappend definitions), removing canonical definitions of return = pure and mappend = (<>) would be good to reduce the future work we need to do.

26 Likes

Thought I’d give a little update on progress so far.

Out of the ~148 packages, I’ve been focussing on the set at the bottom I had processed separately.

  • 19 packages in total have or merged PRs (one of which I’ve confirmed has put out a new release)
  • 4 packages are unmaintained
  • 4 packages refused patches
  • 6 packages have not had any updates in 7+ years, so I decided they were not a priority for now

That leaves ~115 packages left to go.

In further news, the MR to GHC has been approved, but I’ve decided to wait on merging until more packages have been updated.

I am once again requesting help from folks to make these PRs; having done a handful myself, the process is very simple (and takes me ~10 minutes per package):

If a package looks unmaintained, or has already been patched, please let me know and I’ll cross them off the list.

12 Likes

Not sure what’s your stance on the topic of AI but this task seems pretty well suited for giving to an agent with some human supervision, I wanted to do some agentic stuff for a while and this seems like a good excuse, I’d run everything myself and review the final results to ensure that no slop ends up being reviewed by maintainers.

Would you be interested in that?

4 Likes

I’m personally against it, but my concern here would be that you’d be opening prs against so many people’s repos who also all have their own opinions on usage.

I also think that it may genuinely be possible to do this in an automated manner without llms somewhat, I just haven’t pushed to do it yet.
For example, you could:

  1. Iterrate through all these packages
  2. Grab the source repository field if it exists
  3. Clone the repo
  4. Make a new branch
  5. Fork with gh repo
  6. Apply patches that I’ve already provided
  7. Maybe do a little bit of grep and human interaction to check for any missing posts
  8. Pushing up and making a pr

That’s a much more deterministic process and doesn’t require using LLMs at all.

1 Like

Oh I hadn’t realized that you already generated a diff for each repo.

Yes, my plan was basically doing those steps you mentioned but using the LLM to do step 6 since I thought that was the hard part.

That makes everything A LOT easier. I think I can get it done today or tomorrow using the diff.

BTW I’m curious, how did you generate that diff?

1 Like

The good old fashioned way, manually. I had clc-stackage up with my patched ghc, and I would build as much of stackage as possible, and when something failed I would download the source from hackage, initialise a git repo, make a patch, and add that package to the local package overrides before starting the process again.

1 Like

I setup something to automatically fork the repo, apply the patch, build it, run tests and push the resulting code.

Over here you may view the results of the repos: the great patchening · GitHub

The meaning of the results are:

  • failed to apply diff: (31) The diff no longer applies, most of these are because the original patch was created again an old version of stackage, a lot of these mean that the package is already patched.
  • failed to compile: (10) Repo failed to compile after applying the patch
  • last repo commit too old: (13) The last commit is older that 7 years so we don’t patch it
  • could not resolve upstream repo (not found / non-git): (31) Usually cause by repos that do not live in github, and some other cases where the package doesn’t have repo information in the cabal file
  • tests failed: (3) Tests failed to run after applying the patch
  • built; branch pushed to fork: (24) This is the happy path, the repo was built with the patch and everything worked so we create a fork and push the changes

Right now forks are available at monad-of-no-return repositories · GitHub

As I mentioned in private I’ll be leaving for vacations this week for about a month so I could add someone else to the org if you don’t want to wait until I come back.

2 Likes

With the help of @ludat and a little bit of elbow grease, a scattershot selection have been patched.

Additionally I used Bodigrim’s excellent hackage-revdeps to determine which packages should be prioritised based on the number of reverse dependencies; that list can be seen here.

I’m happy to say every package with more than 100 reverse dependencies has had a PR made against it (including Bas van Dijk kindly adding me to the maintainers of case-insensitive).

I don’t want to let the MR against GHC to bitrot, so I’m going to ask the GHC team to merge it if and when they think it appropriate, and I’ll look into further patches in the near future.

If a package you like, use, or maintain is in the list and does not have an MR against it/is not ticked off, please fix it and let me know! If you don’t support old versions of GHC, the patches are as simple as either removing the definition of return/mappend, or moving the definition of return/mappend to pure/(<>) and then removing them.

8 Likes