1. 16

  2. 3

    A package manager needs an algorithm to select package versions

    I used to believe this, too. This problem is part of why I fell in love with Nix / NixOS: the package manager has no “smarts” and makes no “decisions” to determine what versions are viable. Instead, the specific dependencies are passed in by reference.

    1. 2

      Statements concerning Rust do not seem correct. In fact, the article states:

      I mentioned above that there can’t be two definitions of printf built into a C program, but languages with explicit module systems should have no problem including different versions of a package (under different fully-qualified names) into a program.

      This is what Rust does, so the proof does not apply to Rust.

      1. 2

        Most every language I know of behaves the same way, for the reason that if your program gets a Map from library A and a Map from library B, you’d be deeply surprised if they actually referred to different kinds of Map’s. There’s no nice way to have two versions of the same library cohabit in a program.

        1. 2

          The assumptions are true of every package manager I have looked at: […] Rust’s Cargo, Node’s npmjs […]

          It’s also not true of npm. npm installs requested versions as sub-module of the requesting modules.

          As an example from npm’s own node_modules directory:

          1. 1

            edit: i don’t know anything about rusts package system ;) if you think that something isn’t correct, i guess russ likes to hear about that :)

            1. 1

              The proof assumes “Two different versions of a package cannot be installed simultaneously”, but Rust’s Cargo allows it, making the assumption invalid.

              1. 2

                Isn’t rsc just saying that the two different versions of said package have to be distinguished by name? How does Cargo differentiate?

                1. 3

                  Your app depends on library A and library B where A depends on C v1 and B on C v2, cargo will just compile and link both to their respective targets.

                  This issue becomes apparent if A and B expose types from C, as they will not be compatible (and considered different types).