See a typo? Have a suggestion? Edit this page on Github
My
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 MonadBaseControl
to MonadUnliftIO, for reasons I've
discussed
at
length
before and
spoken
about too.
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.
Today
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, likemonad-control, but that number will naturally drop as we move over toMonadUnliftIOexclusively.conduitis designed to provide basic conduit functionality with fewer dependencies. It does depend onresourcet, and packages likemonad-control. But it does not depend onbytestring,text, orvector, even though these are almost always wanted with conduit. It provides theData.Conduit.Listset of combinators, which are not the best ones out there.conduit-extraadds lots of dependencies, including things likeattoparsec, and provides a nicer set of helpers aroundbytestringandtext.- And finally, at the top of the tree (or our tree for today), we've
got
conduit-combinators, which provides the combinators I actually recommend people use in theData.Conduit.Combinatormodule. This has lots of dependencies, since it inherits fromconduit-extraand also adds in some extra things likemwc-random.
Benefits:
- You can use
resourcetwithout touching the conduit ecosystem at all - You can use
conduitwithout pulling in lots of resources Data.Conduit.Combinatorsis fully loaded
Downsides:
- The current dependency footprint even at the base is higher than I'd like, though that's getting fixed soon regardless.
- The
conduitpackage is not super useful on its own due to lack ofbytestring,text, andvectorsupport. - To get the functionality you want in either
conduit-extraorconduit-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 onbytestring,text, andvectoras basic libraries everyone should be using anyway. We move overData.Conduit.Combinatorsand provide most of its functionality inconduititself, and start recommending againstData.Conduit.List,Data.Conduit.Binary, andData.Conduit.Text.conduit-extrabasically remains as-isconduit-combinatorsretains the extra functionality not present in the newconduit
Benefits:
- The
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
Data.Conduit.List
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 ofconduit-combinators, and the simplest path forward for the above is to makeconduitdepend onmono-traversable. However, this is a slightly heavier dependency footprint, requiring adding inunordered-containersandvector-algorithms. Alternatives:- Strip down
mono-traversableto have less deps - Redefine parts of
mono-traversableneeded forconduitinconduititself - Going crazy: really move
mono-traversableintoconduitand swap the dependency tree around - My inclination: minimize
mono-traversable's dependencies a bit more (like dropping thesplitpackage, and maybevector-algorithms) and make it a dependency ofconduit.
- Strip down
- Do we really need
conduit-combinatorsas well asconduit-extra? It's just adding a few extra pieces of functionality overconduit-extra, and perhaps those should be folded intoconduit-extraitself. - Some people may not like the heavier dep footprint of
conduitnow. Should we split off aconduit-corepackage providing the core data types, functions, and operators, and haveconduitdepend 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 theresourcetpackage itself, and then we can turnresourcetinto a backwards compatibility layer. - Or it may be logical to place
ResourceTin theunliftio-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.