Open dminuoso opened 3 years ago
I'm am somewhat against this change because I don't think the benefit from this is worth the cost. In libraries where I need to represent, for example, IPv4 addresses, but I don't need any of the machinery from ip
, I typically just use a Word32
. But let's consider how this would need to be set up, just in case the tide ever changes. We would need:
ip-core
(data types, instances for things from base
, probably basic stuff like smart constructors and operations with masks)ip-platform
(parsers and builders for types from text
and bytestring
)ip-aeson
(orphan json typeclass instances, depends on ip-platform
)ip-bytes
(stuff with the byte*
libraries)ip
(Reexports everything include orphan json instances)I think that's how it would get split up if we were going to do this. But at the moment, I'm not convinced that this is really worth doing.
This library has 75 transitive dependencies, roughly ~50 of which are from aeson alone.
This drives up compilation time, makes auditing transitive updates harder, increases build plan complications (as a nix user this regularly affecfts me), and has quite a hefty penalty on object size in the absence of split sections + stripping. And it might deter some users.
A simple IP library should not have some "batteries-included" type of footprint like a web framework.
This library has 75 transitive dependencies, roughly ~50 of which are from aeson alone.
This drives up compilation time, makes auditing transitive updates harder, increases build plan complications (as a nix user this regularly affecfts me), and has quite a hefty penalty on object size in the absence of split sections + stripping. And it might deter some users.
A simple IP library should not have some "batteries-included" type of footprint like a web framework.
I've been writing rust for a while now and one thing their packages have, which I wish Haskell's did, is feature flags. Feature flags can be on or off by default. In some cases, feature flags can be used to distinguish between async runtimes (example). They're a very versatile feature with a high power-to-weight ratio and smooth UX. In Haskell we have CPP flags, which are more annoying to use, but get the job done. In short, I think these features should be behind CPP flags, and be on or off by default depending on what's reasonable. They're easy enough to override with cabal, stack, and nix. You won't get caching with nix this way, though, unless nixpkgs or haskell.nix start doing something with combinations of flags (doubtful), or unless you start hosting your own infra (which I have done many times).
Splitting stuff out into multiple packages achieves the same effect but with more burden on maintainers, IMO.
So this is an interesting proposition. The main downfall is that flags cannot be specified in .cabal files, they are cabal.project settings. Because of this aeson
and byte*
would have to be enabled by default. Also, any user who does disable these should probably make sure it builds with these flags enabled as well, but that's just for their sake.
Added benefit is that it has no impact on all existing users. Thoughts @andrewthad?
I'd be willing to implement this.
So this is an interesting proposition. The main downfall is that flags cannot be specified in .cabal files, they are cabal.project settings. Because of this
aeson
andbyte*
would have to be enabled by default. Also, any user who does disable these should probably make sure it builds with these flags enabled as well, but that's just for their sake.Added benefit is that it has no impact on all existing users. Thoughts @andrewthad?
I'd be willing to implement this.
To my knowledge, cabal.project just creates the relevant arguments for Setup.hs, though without the cabal.project I believe that you must specify flags at the command line with eg --constraint='pkg +flag'
.
However I don't really think this is much of a downside, cabal.projects are so useful, to the point I use them in most of my projects and I wish they were just part of .cabal, and stack and nix already support this option without additional files.
I'm fine with a feature flag that removes the aeson
dependency (and all related instances). If anyone wants to implement this, I would accept a PR.
Right now the presence of the
aeson
andbyte*
dependencies makes for a sizable footprint ofip
. This to me makesip
an uninteresting candidate for use in libraries that just need to carry IP or Mac data around, but may not even have to parse them (or it parses them directly off a wire protocol).The typical choice seems to be, to provide a package
ip-core
that exposes only the basic types/bindings/instances, and thenip
as a wholesale meal with orphan instances and parser utilities. This is similar to theyesod-ip
package.Aside from bumping a major version to satisfy PVP, this should have no other impact on users.
What do you think? I'd be willing to do the work to get it done.