Breaking changes, dependency trees
This commit is contained in:
parent
66f35c33f8
commit
e6068b923c
2 changed files with 132 additions and 0 deletions
|
@ -1,3 +1,7 @@
|
|||
- file: posts/breaking-changes-dependency-trees.md
|
||||
title: "Breaking changes, dependency trees"
|
||||
time: 2018-01-09T12:00:00Z
|
||||
description: "Some thoughts on upcoming library breaking changes, and how to restructure dependency trees"
|
||||
- file: posts/drop-conduits-finalizers.md
|
||||
title: "Drop Conduit's Finalizers?"
|
||||
time: 2018-01-03T13:57:00Z
|
||||
|
|
128
posts/breaking-changes-dependency-trees.md
Normal file
128
posts/breaking-changes-dependency-trees.md
Normal file
|
@ -0,0 +1,128 @@
|
|||
My
|
||||
[previous blog post](https://www.snoyman.com/blog/2018/01/drop-conduits-finalizers)
|
||||
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](https://www.fpcomplete.com/blog/2017/06/tale-of-two-brackets)
|
||||
[at](https://www.fpcomplete.com/blog/2017/06/readert-design-pattern)
|
||||
[length](https://www.fpcomplete.com/blog/2017/07/announcing-new-unliftio-library)
|
||||
[before](https://www.fpcomplete.com/blog/2017/07/the-rio-monad) and
|
||||
[spoken](https://www.snoyman.com/reveal/monad-transformer-state)
|
||||
[about](https://www.youtube.com/watch?v=KZIN9f9rI34) 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](https://github.com/snoyberg/codename-karka/#refactor-michaels-existing-libraries-to-match),
|
||||
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:
|
||||
|
||||
* `resourcet` is 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 `MonadUnliftIO` exclusively.
|
||||
* `conduit` is 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 `bytestring`,
|
||||
`text`, or `vector`, even though these are almost always wanted with
|
||||
conduit. It provides the `Data.Conduit.List` set of combinators,
|
||||
which are not the best ones out there.
|
||||
* `conduit-extra` adds _lots_ of dependencies, including things like
|
||||
`attoparsec`, and provides a nicer set of helpers around
|
||||
`bytestring` and `text`.
|
||||
* 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 the `Data.Conduit.Combinator` module. This
|
||||
has lots of dependencies, since it inherits from `conduit-extra` and
|
||||
also adds in some extra things like `mwc-random`.
|
||||
|
||||
Benefits:
|
||||
|
||||
* You can use `resourcet` without touching the conduit ecosystem at all
|
||||
* You can use `conduit` without pulling in lots of resources
|
||||
* `Data.Conduit.Combinators` is 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 `conduit` package is not super useful on its own due to lack of
|
||||
`bytestring`, `text`, and `vector` support.
|
||||
* To get the functionality you want in either `conduit-extra` or
|
||||
`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, `resourcet` drops a bunch of
|
||||
dependencies. Nothing too interesting there.
|
||||
* `conduit` adds a dependency on `bytestring`, `text`, and `vector` as
|
||||
basic libraries everyone should be using anyway. We move over
|
||||
`Data.Conduit.Combinators` and provide most of its functionality in
|
||||
`conduit` itself, and start recommending against
|
||||
`Data.Conduit.List`, `Data.Conduit.Binary`, and `Data.Conduit.Text`.
|
||||
* `conduit-extra` basically remains as-is
|
||||
* `conduit-combinators` retains the extra functionality not present in
|
||||
the new `conduit`
|
||||
|
||||
Benefits:
|
||||
|
||||
* The `conduit` package now provides most of the functionality you'll
|
||||
want on a day-to-day basis
|
||||
* The dependency footprint for the `Data.Conduit.Combinators` module
|
||||
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-traversable` package? It's currently a
|
||||
dependency of `conduit-combinators`, and the simplest path forward
|
||||
for the above is to make `conduit` depend on
|
||||
`mono-traversable`. However, this is a slightly heavier dependency
|
||||
footprint, requiring adding in `unordered-containers` and
|
||||
`vector-algorithms`. Alternatives:
|
||||
* Strip down `mono-traversable` to have less deps
|
||||
* Redefine parts of `mono-traversable` needed for `conduit` in
|
||||
`conduit` itself
|
||||
* Going crazy: _really_ move `mono-traversable` into `conduit` and
|
||||
swap the dependency tree around
|
||||
* My inclination: minimize `mono-traversable`'s dependencies a bit
|
||||
more (like dropping the `split` package, and _maybe_
|
||||
`vector-algorithms`) and make it a dependency of `conduit`.
|
||||
* Do we really need `conduit-combinators` as well as `conduit-extra`?
|
||||
It's just adding a few extra pieces of functionality over
|
||||
`conduit-extra`, and perhaps those should be folded into
|
||||
`conduit-extra` itself.
|
||||
* Some people may not like the heavier dep footprint of `conduit`
|
||||
now. Should we split off a `conduit-core` package providing the core
|
||||
data types, functions, and operators, and have `conduit` depend on
|
||||
that?
|
||||
* It feels almost silly to have the `ResourceT` data 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
|
||||
`resourcet` package itself, and then we can turn `resourcet`
|
||||
into a backwards compatibility layer.
|
||||
* Or it may be logical to place `ResourceT` in the `unliftio-core`
|
||||
package, 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 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.
|
Loading…
Reference in a new issue