Join GitHub today
GitHub is home to over 28 million developers working together to host and review code, manage projects, and build software together.Sign up
Question: Why 'Flat' Dependencies #89
I'm new to elm. I wanted to know why elm & elm-package were designed in a way, where all packages are installed locally (which is good) but in a flat structure, and of course - are there any plans on evolving it?.
I guess that from the compiler point-of-view it's much easier to implement this mechanism, but when the 'eco-system' will grow it will happen much frequently, and it will be unpleasant. I have to say it worries me, as someone who is considering using elm-lang. I'm coming from node, where npm really does a good job in managing dependencies.
As I said, I'm new to elm, so there's a chance I misunderstood how packages work
Elm is statically typed, so we'd need to introduce a construct to know that
It gets event more complicated when somewhere in the api of a package there's a function that returns a type from a different package - I'm not aware of a good solution for it (there is this notion of peer dependency, where you specify a restriction of a companion/sibling package)
This choice was made intentionally. I have researched this quite a lot and weighed the tradeoffs for quite a while. Unfortunately, I have not done a big writeup about all of this yet!
Imagine that version 1.0.0 of
One way to deal with this is to treat the list types differently, so
I personally think the question should be "how can we make things pleasant?" The tradeoffs in JS are not the same ones faced here. The longer term plan for
I'm not sure I understand. If there are 10 versions of List, why not just take the highest one? (if it's stable and hadn't change much - if there was a major change you have a problem either way)
Essentially, what you are saying, let's restrict it from the beginning - all your packages that use List must use the same version or your project will not compile (which is a really good restriction), but (prepare for success) when many packages will be built, you have to make them use the same version you do (and the tree can get complex). If the major version doesn't change - no problem, but if it does, it's an issue. That's why I think we should differentiate between inner dependencies to ones you give in your package API. It's good restriction for an 'outer' dependency, but for an 'inner' one, does it matter?
Another point, is that the error is weird (Unable to find a set of packages that will work with your constraints.).
I'm not talking about a specific issue, it's just an example I faced the first day trying to use elm-package - of course it doesn't mean you see it everywhere.
I think that's it
Yep, point 1 is a known technique that we have considered. We can determine public/private dependencies automatically based on API to a point. The only problem is that values can leak through that do not appear in types, which we have no way to detect reliably. This may be particular constants or anonymous functions. It is not clear how big of a problem that is, so I would want to figure out the worst possible tricks we could do. Perhaps nothing catastrophic like what I described in my earlier comment can happen? I have thought it through well enough to say that with confidence though, and the policy in Elm in general is "adding freedom is easy, taking it away is hard" so err on the side of caution when you are not sure about something that has big implications.
Overall, you should know that this is a young project. This is essentially the first draft of a lot of things, and there are a ton of plans of how things will develop, mostly around more automated testing and automatically expanding version bounds. To make it clearer how new this is: this is the first version that actually does any dependency solving at all.
I think points 2 and 3 in your latest comment deserve issues to track progress on this if they can be made specific. In particular, dependency solving is relatively rudimentary right now, so that may be relatively easy to improve error messages. That is vital to creating the best
For point 3, you can think of the current "dependencies" listing as "public-dependencies" and there just are no private dependencies right now. It seems plausible to incorporate changes there into the version bump calculation, but I am not sure what the rules should be really. It'd be good to have a set of cases where a dependency can introduce major or minor changes and see to what extent that can be detected statically.
referenced this issue
Feb 16, 2016
@evancz Is it possible to remove partial functions altogether? Then you could actually determine public/private dependencies and that would solve the problem in the best way.
It seems as though whatever can be expressed with partial functions could be expressed in other ways. The obvious one:
Prelude> :type head head :: [a] -> a Prelude> head  *** Exception: Prelude.head: empty list
head : List a -> Maybe a head  == Nothing