Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Revisiting policy on dependencies #95

Open
dmcclean opened this issue Nov 4, 2015 · 11 comments
Open

Revisiting policy on dependencies #95

dmcclean opened this issue Nov 4, 2015 · 11 comments
Labels

Comments

@dmcclean
Copy link
Collaborator

dmcclean commented Nov 4, 2015

I think it's valuable to keep our current policy of minimizing dependencies as much as possible, because that can help enable maximal adoption and hopefully unite the community around one dimension tracking library, which is good for everyone.

On the other hand, Haskell makes this difficult. There are a whole bunch of features that I would like to add that would require orphan instances if done in another library, and orphan instances are really problematic in practical ways, not just as a smell.

In the continued absence of some kind of "forward instance declaration" scheme or a better module system (both discussed here https://www.reddit.com/r/haskell/comments/2rajq1/is_there_anything_planned_to_solve_the_orphan/), what do we do about this?

Package flags seem like almost as much of a misfeature as orphan instances, because package installations are global and there is no clear way to determine how to set the flags or document the relationship between dependencies and flag settings, but I am considering it.

@dmcclean
Copy link
Collaborator Author

@bjornbm If you have a minute, could you comment on this?

In particular things like #8 require taking a dependency on either parsec or attoparsec but as they don't involve instances could also be split out into another page dimensional-parsing or the like. Ditto for various proposed TH features, some of which are necessary to get good mileage out of the #97 effort. If we go the separate packages route, are you OK with restructuring the folders to move down one level and keeping development for all of them in the same github repository so that the issues and any revisions that impact multiple libraries will be linked?

Things that do benefit from instances are trickier but also further down the road.

@dmcclean
Copy link
Collaborator Author

Instances would be useful for interoperating with these, possibly among others: linear, vector-space, HaTeX, ihaskell.

@bjornbm
Copy link
Owner

bjornbm commented Nov 24, 2015

If we go the separate packages route, are you OK with restructuring the folders to move down one level and keeping development for all of them in the same github repository so that the issues and any revisions that impact multiple libraries will be linked?

Yes, this is OK with me.

Instances would be useful for interoperating with these, possibly among others: linear, vector-space, HaTeX, ihaskell.

Depending on the API of a given library perhaps orphan instances could be avoided by providing a newtype wrapper for a given dependency and defining instances for the newtype. The newtype and instances would be defined in the same module (e.g., Numeric.Units.Dimensional.Linear of package dimensional-linear). Again, not sure how feasible this is and if wrapping/unwrapping would add too much noise in client code to make it palatable. A small API could be replicated with automatic wrapping/unwrapping but for a large API that is not a very attractive option.

@dmcclean
Copy link
Collaborator Author

OK, tentative plan is below:

Make 4 projects

  • dimensional
  • dimensional-codata (split off from dimensional-dk-experimental, only outside of dimensional itself because they change it periodically, potentially could be consolidated?)
  • dimensional-parsing which will take an attoparsec dependency and tackle the parsing issues
  • dimensional-th which will provide template haskell splices and a quasiquoter that are useful for users of the fixed point features who don't love typing out their type-level numbers in an immensely wordy way

Additionally, make two package flags (for linear and for vector-space) which are off by default. When turned on, they incur the corresponding dependency and provide the corresponding instances. This is a hacky solution because it burdens people to turn the flag on, because otherwise they will get a compile error, but at least it provides some path to getting these features without orphan instances. IMO the newtype thing is unworkably noisy because all the arithmetic operators would need to be wrapped with yet another layer of wrappings, and that is a fairly large API surface (~30 exports, not counting .FixedPoint or worse .Quantities).

@dmcclean
Copy link
Collaborator Author

Similar flags for aeson, binary, and any other serialization instances that anyone eventually wants.

@dmcclean
Copy link
Collaborator Author

dmcclean commented Dec 1, 2015

The downsides to restructuring and keeping everything in one repo are more obvious once I started to do it. Of note are issues with setting up the CI build(s) and with release tagging and github releases. Branching cuts both ways.

Creating multiple projects for now, we can consolidate them later if referring issues around or managing keeping releases in sync gets to be too much of a hassle.

@dmcclean
Copy link
Collaborator Author

dmcclean commented Dec 1, 2015

Spun off:

Primarily just boilerplate for appeasing git, cabal, and travis. Substantive commits to come, along with hackage release for dimensional-codata since it is essentially already finished in dimensional-dk-experimental and just could use some haddocks.

@dmcclean
Copy link
Collaborator Author

dmcclean commented Dec 1, 2015

Do you happen to understand the manual property of cabal package flags?

@bjornbm
Copy link
Owner

bjornbm commented Dec 3, 2015

Not familiar with it, but my interpretation of the user guide is that if
manual is true only the default flag value will be tried, and cabal will
not fall back to the negated value.

On Tue, Dec 1, 2015 at 2:44 PM, Douglas McClean [email protected]
wrote:

Do you happen to understand the manual property of cabal package flags?


Reply to this email directly or view it on GitHub
#95 (comment).

@dmcclean
Copy link
Collaborator Author

dmcclean commented Dec 3, 2015

I think it would be useful to take the groups dependency. We are swimming in groups. I might even be missing some, but at least we have:

  • instance Group ExactPi
  • instance Group Dimension'
  • instance Fractional a => Group (Quantity d a)
  • instance Fractional a => Group (Unit 'NonMetric d a)
  • instance Fractional a => Group (AnyQuantity a)
  • instance Fractional a => Group (DynQuantity a)
  • instance Group AnyUnit
  • instance Group (UnitName 'NonMetric)

Pros: we can express this, and not need so many conflicting names (although we will keep all the names, it means that some of our modules use 3 or 4 different qualified (*) and recip definitions.
Cons: for some reason the groups package has almost no reverse dependencies, and for some equally strange reason there isn't a movement to pull it in to base.

@bjornbm
Copy link
Owner

bjornbm commented Dec 5, 2015

Looks like groups is stable with virtually no risk if we pin the version number.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants