Maybe my thoughs about how to evolve Nim's stdlib and Fusion are not good enough for an RFC yet, but here is it anyway, https://github.com/nim-lang/RFCs/issues/310
Feedback appreciated, but please comment and vote on github and not here.
I'm not a stakeholder in nim, so I don't want to pollute the RFC, but I wanted to share that the "diamond" problem that arne and disruptek discussed is something that I've seen.
What we did in that case is actually sort of similar to what Araq initially proposed. We had version folders (eg v1, v2, v3, etc) and whenever a backwards incompatible change would be introduced (and we were pretty strict about semver), then that module would instead be copied into the next version folder. Ie: change to v1/foo is breaking -> leave v1/foo as is, and now that change and all future changes (except for backwards compatible bugfixes) go to the new v2/foo. So there is no mass migration to v2, v3, etc. Instead modules only promote when they break consumers. We also had a latest folder for development that just pointed to the newest version, so you didn't need to know that bar was on v6 until you needed stability. Note that I'm not proposing this as a solution to use in nim, it has issues, but I think some solution to the problem is desirable.
We had code that accepted data from multiple versions and would need to dispatch to functions from the appropriate module version. Thinking about how that code could be written in nim is actually what inspired my comment about "warts" here: https://forum.nim-lang.org/t/6593#40905 (Basically I'd be sad to have to drop UFCS just because I'd need to be writing v1foo.procedure and v2foo.procedure everywhere.)
Symbol renaming is indeed how modern languages / environments solve the issue:
https://stackoverflow.com/questions/11016220/what-are-inline-namespaces-for
https://stephencoakley.com/2019/04/24/how-rust-solved-dependency-hell
https://developers.redhat.com/blog/2019/08/01/how-the-gnu-c-library-handles-backward-compatibility/
The key insight here is that different versions of code is different code and should be treated as such.
https://doc.rust-lang.org/cargo/reference/specifying-dependencies.html treats different scenarios in depth as well.
Minimal versioning is indeed a nice idea because it helps increasing the chance of selecting versions that someone's actually tried to use at least once - another strategy would be to somehow tie version selection to a success list according to CI - but that's uh, far off. https://about.sourcegraph.com/blog/the-pain-that-minimal-version-selection-solves/ gives a nice overview.
What version nimble picks depends on what nimble commands you ran before - sometimes it's the earliest one, but mostly it's quite random :)