The only once constraint also has a nice out for the SAT solver, if you reach a conflict or something that can't be solved cheaply you just make the user select a version that may not be compatible with the constraints. Bower, dep, and maven work that way.
So, I'm not sure how happy I would be as a user if my package installer bailed out and asked me to choose!
Out of curiosity, how do you mark your package as "only once" in cargo? I tried googling, and didn't find an answer, but did find a bug where people couldn't build because they ended up depending on two different versions of C libraries!
It does make wonder if MVS will solve real pain in practice. :-)
Its definitely not a great UX, but at the end of the day the problem can only be solved at the language level or by package authors choosing new names. For instance in java you can't import 2 major versions of a package. Solving for minor versions having to bail out has been incredibly rare in my experience. I only see it when there's "true" incompatibilities, e.g.
foo: ^1.5.0 bar: foo (<= 1.5)
> Out of curiosity, how do you mark your package as "only once" in cargo? I tried googling, and didn't find an answer, but did find a bug where people couldn't build because they ended up depending on two different versions of C libraries!
I think its the `links = ""` flag. It may only work for linking against C libraries at the moment, but cargo understands it!
> It does make wonder if MVS will solve real pain in practice. :-)
Not by itself, the semantic import versioning is the solution to the major version problem, by giving major versions of package different names. Go packages aren't allowed to blacklist versions, though your top level module is. This just means that package authors are going to have to communicate incompatible versions out of band, and that the go tool may pick logically incompatible versions with no signal to the user beyond (hopefully) broken tests!
1. Singletonish things like global allocators, rayon-core, etc
2. You may have made a package static safe to mutate with a mutex, but it could be a bad thing to have different versions of that mutex.
3. Compile time computed tables (unicode table, perfect hashes, etc) could be imported multiple times ballooning the binary.
4. ABI/type compatibility with any reexported types
Yeah, go has a magic function `func init()` which gets called before main. (You can actually have as many init's as you want, and they all get called.)
Probably evil, though so far it hasn't hurt me in the same way as, e.g., c++ constructors have. Maybe because it's more explicit and thus you're less likely to use it in practice.