See a typo? Have a suggestion? Edit this page on Github
previous blog post
discussed a possible upcoming breaking change to the conduit library:
dropping finalizers. This is one of a number of other breaking changes
I have planned. Another one is switching over from
MonadUnliftIO, for reasons I've
Beyond this change, I have a number of others planned out as well, some more solidly than others. I've started a document describing some of these, and I wanted to bring up one point in this design space for some user feedback: conduit dependency trees.
The situation today is that we have a dependency graph that looks something like the following:
resourcetis at the base of the hierarchy, and defines some non-conduit-specific types and functions used throughout the conduit ecosystem. It currently depends on a number of packages, like
monad-control, but that number will naturally drop as we move over to
conduitis designed to provide basic conduit functionality with fewer dependencies. It does depend on
resourcet, and packages like
monad-control. But it does not depend on
vector, even though these are almost always wanted with conduit. It provides the
Data.Conduit.Listset of combinators, which are not the best ones out there.
conduit-extraadds lots of dependencies, including things like
attoparsec, and provides a nicer set of helpers around
- And finally, at the top of the tree (or our tree for today), we've
conduit-combinators, which provides the combinators I actually recommend people use in the
Data.Conduit.Combinatormodule. This has lots of dependencies, since it inherits from
conduit-extraand also adds in some extra things like
- You can use
resourcetwithout touching the conduit ecosystem at all
- You can use
conduitwithout pulling in lots of resources
Data.Conduit.Combinatorsis fully loaded
- The current dependency footprint even at the base is higher than I'd like, though that's getting fixed soon regardless.
conduitpackage is not super useful on its own due to lack of
- To get the functionality you want in either
conduit-combinators, you end up with a much larger dependency footprint.
Plans for the next version
I have a number of different ideas in mind. I'll start off with the most conservative plan, and mention some variants below.
- As already mentioned,
resourcetdrops a bunch of dependencies. Nothing too interesting there.
conduitadds a dependency on
vectoras basic libraries everyone should be using anyway. We move over
Data.Conduit.Combinatorsand provide most of its functionality in
conduititself, and start recommending against
conduit-extrabasically remains as-is
conduit-combinatorsretains the extra functionality not present in the new
conduitpackage now provides most of the functionality you'll want on a day-to-day basis
- The dependency footprint for the
Data.Conduit.Combinatorsmodule is much reduced
- We can finally get away from the not-well-named functions in
There aren't necessarily downsides to this approach, as I think it's simply better than what we have today already. But I want to list out the alternatives, which will make clear some things that could be possibly better still.
- What do we do with the
mono-traversablepackage? It's currently a dependency of
conduit-combinators, and the simplest path forward for the above is to make
mono-traversable. However, this is a slightly heavier dependency footprint, requiring adding in
- Strip down
mono-traversableto have less deps
- Redefine parts of
- Going crazy: really move
conduitand swap the dependency tree around
- My inclination: minimize
mono-traversable's dependencies a bit more (like dropping the
splitpackage, and maybe
vector-algorithms) and make it a dependency of
- Strip down
- Do we really need
conduit-combinatorsas well as
conduit-extra? It's just adding a few extra pieces of functionality over
conduit-extra, and perhaps those should be folded into
- Some people may not like the heavier dep footprint of
conduitnow. Should we split off a
conduit-corepackage providing the core data types, functions, and operators, and have
conduitdepend on that?
- It feels almost silly to have the
ResourceTdata type live in a separate package.
- If we have
conduit-core, that could be a logical place to put it, since it won't have any extra dependencies versus the
resourcetpackage itself, and then we can turn
resourcetinto a backwards compatibility layer.
- Or it may be logical to place
unliftio-corepackage, since both concepts help with resource cleanup in monad transformers. The former is necessary for continuation-based monads, while the latter (
MonadUnliftIO) works for simpler monads.
- If we have
If people have feedback, I'm happy to hear about it. I've spent an unfortunate amount of time bouncing around between these different options, so hopefully writing it all down and hearing some outside opinions can help move this forward.