cross-posted from: https://sh.itjust.works/post/64685863

Lots of programming languages have their own package manager, separate from the distribution or OS package manager.

Going loosely from the TIOBE index:

  • Python has Pip
  • C# has NuGet
  • Javascript has npm for Node.js
  • Visual Basic also uses NuGet
  • R has a repository of packages that can be installed by running install.packages("something") in R
  • Rust has Cargo/Crates
  • Go has the go get command
  • Swift has its own package manager swift package
  • Ruby has RubyGems
  • Java has Maven and Gradle (not sure if they are full package managers, or build automation tools with dependency resolution)
  • PHP has Composer for managing libraries and dependencies
  • C and C++ are the only exceptions I can think of, off the top of my head; libraries are managed by, and coupled to, the operating system
  • trem@lemmy.blahaj.zone
    link
    fedilink
    arrow-up
    4
    ·
    10 hours ago

    You want some way to define package versions in your repository, so that you can check out an earlier commit or a different branch and still have a working build. Because you do often need to adjust the code in your repo when dependencies get updated.

    And going upwards from there, I think that languages are just a point where it’s quite natural for this to be solved, since the language creators care to build up an ecosystem and it does help when you can make language-specific assumptions.

    I do think, it’s possible to create a package manager that spans across programming languages, like Nix is starting to be viable for.
    But you need that to be ready when a new programming language is starting to take off. For all the languages you listed, that choice was made many years ago and you can’t easily reverse it.

  • Caveman@lemmy.world
    link
    fedilink
    arrow-up
    29
    ·
    1 day ago

    It’s because it’s the greatest thing since compilers. Having a clear “this is how packages interact” rules and “autodownload dependencies” solves a massive headache. C/C++ packages are basically the wild west.

  • tatterdemalion@programming.dev
    link
    fedilink
    arrow-up
    7
    ·
    23 hours ago

    In the case of Rust, it makes sense both as a UX win and a way to abstract certain requirements of the build system. Languages don’t agree on how to do things like linking packages into a binary or versioning packages. If Rust left all of that unspecified, we’d probably have multiple competing package managers and ecosystems.

  • dohpaz42@lemmy.world
    link
    fedilink
    English
    arrow-up
    48
    ·
    2 days ago

    Throwing in my two cents:

    I would imagine package managers are because of C and C++ not having package managers. I remember 20+ years ago before package managers were a thing, before the Debians, Ubuntus, and Arch (btw)s (before autoconf and configure), when we would download software and have to compile it ourselves, and the lack of reliable means of knowing what dependencies were needed to compile said software. Repeat this ad nauseam for each dependency that itself had dependencies.

    It was Hell.

    ~I for one am grateful for my dependency-resolving overlords. 🙇‍♂️~

    • Theoriginalthon@lemmy.world
      link
      fedilink
      arrow-up
      7
      ·
      23 hours ago

      This is how I got started with Linux. On windows to play media you needed various codec packs and loads of other bullshit. Then I discovered VLC that just worked, and was free? What’s this opensource thing is it like freeware? Then my whole computing world opened up.

    • chaospatterns@lemmy.world
      link
      fedilink
      English
      arrow-up
      3
      ·
      23 hours ago

      Now you have two package managers. The problem is that Nix needs to create a folder structure that matches what your language package manager wants to see.

      Even if the language package manager goes away, languages have slight differences that can’t be totally abstracted away. C/C++ have .h and .c files. JS has its own thing, C# has a .dll. Each language has difference opinions on how symbols get resolved.

  • staircase@programming.dev
    link
    fedilink
    arrow-up
    52
    arrow-down
    1
    ·
    2 days ago

    If you’ve ever tried using bazel, you might understand why writing a single package manager for multiple languages is a bad idea (at least, that’s why I assume bazel is so god-awful)

    • FizzyOrange@programming.dev
      link
      fedilink
      arrow-up
      2
      ·
      15 hours ago

      It’s not that it’s a bad idea, it’s more that it’s basically impossible at this point.

      Bazel can’t use Cargo, CMake and so on for downloading & building packages because it is trying to do cross-language builds the right way - a single build graph that includes everything. No other third party package managers/build tools actually exposed their build graphs - only commands to perform builds, which are too coarse for Bazel.

      To put it simply, its necessary if you are doing things at the scale of Bazel.

      • staircase@programming.dev
        link
        fedilink
        arrow-up
        14
        ·
        1 day ago

        It’s been a while since I used it in earnest, so my memory is hazy enough that I can’t be specific. One of the largest pieces of work I’ve done in C++ was not writing C++, but working out how to ask bazel to build a single shared library that imports other bazel libraries. I’ve never used such a confusing and frustrating package manager. It was frequently unclear how to do things, despite the project having quite a lot of documentation.

        When I read it supports multiple languages, I had two thoughts:

        • Why? That feels like trying to write a single style sheet for both English and Mandarin.
        • That might explain why it’s so confusing. I surmised: I has to bend over backwards to support all these different languages and their different module and packages architectures. And it doesn’t manage to hide that complexity from the user.
        • onlinepersona@programming.dev
          link
          fedilink
          arrow-up
          3
          ·
          1 day ago

          Thank you. I didn’t expect that because I assume that packages are basically the same everywhere you go (at least in my experience). And managing them is basically solving dependency trees, then downloading files and putting them in the right place for the import system to find them.

          But my experience with programming languages is limited. I haven’t found a language that doesn’t work this way.

          • RaphaelSchmitz@feddit.org
            link
            fedilink
            arrow-up
            1
            ·
            13 hours ago

            I got the same feeling that it shouldn’t be rocket science. Then again, I’m most experienced with C#, which is just a very clean and professional ecosystem, and I often experience that other languages can feel rough around the edges in comparison. E.g. in npm JS, different package managers create entirely different folder structures, even though the build system is 100% the same!

            So maybe a package manager for C# would be straightforward, while npm JS would require a bunch of research about what happens behind the scenes.

            And if other languages are similar to npm JS, it’s easy to imagine that your want to keep languages separated for cleanliness - but then you kinda just get a bunch of one-language-package managers in a trenchcoat, so why even bother. OR you have the same code handling it all, becoming a bit of a mess.

            • KubeRoot@discuss.tchncs.de
              link
              fedilink
              English
              arrow-up
              1
              ·
              1 hour ago

              Worth noting is that C# generally uses compiled libraries, not quite binaries but CIL rather than source code, so that’s what you get when adding references and NuGet packages. And at the same time, compiled C# files include a lot of metadata about the code, like class structure and method signatures, so one .DLL is all you need to use a library.

              NPM is a more complex situation. To say there is one build system is already misleading, since there isn’t a build system built into JS - packages can be source distribution, or they can use a variety of tools, minifiers, packages for web or for Node, and occasionally include native libraries/binaries or otherwise compile native code from other sources.

              I think generally new languages have their own package managers primarily because older languages weren’t planned for convenient dependency management, so solutions for that are stapled on top of their stuff, aren’t compatible with existing libraries, often have some annoyances, and there are often multiple alternatives that were independently developed. On the other hand, new languages can just plan things out from the start, tweaking the language to work well for libraries, and establishing a single tool to avoid fragmentation.

  • terabyterex@lemmy.world
    link
    fedilink
    arrow-up
    42
    arrow-down
    2
    ·
    2 days ago

    i dont understand why you are confused. are you suggesting they should be in the OS? so each library has to be managed at least 6 times and then the ides and language tools have to support all these different stores? i bet ci/cd would just be awesome

    or are you suggesting that all language maintainers work together in harmony and support one another?

    C and C++ dont have package managers because they are older than the concept.

    • Ghoelian@piefed.social
      link
      fedilink
      English
      arrow-up
      7
      ·
      2 days ago

      Having a project’s dependencies in the project dir also makes more sense imo, because these are generally packages that nothing else on the system needs.

    • Lucy :3@feddit.org
      link
      fedilink
      arrow-up
      3
      arrow-down
      7
      ·
      edit-2
      24 hours ago

      And I prefer C/C++ and Python due to that.

      Eg. JS devs need to version pin in NPM to not expose users to compromised packages. That means that, from now on, they need to be active at least every week and update the pinning to not expose users to vulnerable packages. Meanwhile, the users need to be on-edge about the dev actually being active, and, still, for every vulnerability and compromised package, need to scan their whole system for files relating to that package. And of course, that means a very long fix path of Vuln discovered -> Vuln fixed -> Dev knows that one of the dozen packages they use needs updating -> Dev updates -> Package managers updates -> User updates.

      It’s a horrible experience for sysadmins. I’m actively switching to alternatives and rewriting smaller things in C++, because everything I’ve written in the latter has never broken in years, without recompilation, because the ABI stayed the same for all libraries, while the libraries get carefully curated by a dedicated team. And as soon as a vulnerability/backdoor is found and fixed? sudo pacman -Syu. nothing more, nothing less. Fix path: Vuln discovered -> Vuln fixed -> Package managers updates -> User updates.

      Looking at more than just binary files in repos: I’m also actively rewriting PKGBUILDs to use the native python packages instead of building a venv, because that just works better in my experience. I’ve never had issues with incompatibility between python-* packages, simply because they are build for each other. And I mean, it took 30 minutes to build a component that converts a requirements.txt, which requires you to trust the dev (to be active) and pypi (which you can’t trust), to a collection of pacman packages. Universally applicable to all requirements.txt and uncomplicated. So yeah, idiots can continues using pip, I laugh with a list of packages neatly curated by a dedicated team.

      • FizzyOrange@programming.dev
        link
        fedilink
        arrow-up
        3
        ·
        15 hours ago

        I don’t know why you think Python is fine but Typescript isn’t. With modern Python best practice (project.toml and uv) they have basically the same behaviour and caveats. Python is actually a little worse because most Python packages don’t use semver.

  • Feyd@programming.dev
    link
    fedilink
    arrow-up
    28
    ·
    2 days ago

    CPAN for perl was the first one and it was very successful so got copied.

    separate from the distribution or OS package manager.

    Because it is way easier to manage them this way rather than have every distro package repo also support them. Additionally, windows and Mac are also targets and they don’t have built in package managers.

    C and C++ are the only exceptions

    It is not as popular but https://conan.io/ exists. Personally, I miss working in c++ because the lack of a built in package manager made people manage dependencies more thoughtfully. It was not without tradeoffs but I preferred that world to adding a dependency being one command away.

    • Miaou@jlai.lu
      link
      fedilink
      arrow-up
      3
      ·
      23 hours ago

      the lack of a built in package manager made people manage dependencies more thoughtfully

      Unless your colleagues are idiots and now you get to maintain your own homemade “package” “manager”. I find conan to be bidet in a world of diarrhea.

    • Pamasich@kbin.earth
      link
      fedilink
      arrow-up
      3
      ·
      1 day ago

      Additionally, windows and Mac are also targets and they don’t have built in package managers.

      Windows does have a built in package manager: winget.

      • Feyd@programming.dev
        link
        fedilink
        arrow-up
        8
        arrow-down
        1
        ·
        1 day ago

        Sure, but it’s only 6 years old, much newer than every one in this post, to my knowledge only has applications rather than libraries, and sources packages from the windows store or the community repository which is just manifests rather than the actual code or binaries.

        In other words you’re technically correct, but it’s rather irrelevant

  • thingsiplay@lemmy.ml
    link
    fedilink
    arrow-up
    25
    arrow-down
    2
    ·
    2 days ago

    Because you don’t want a single operating system manage the entirety of the Rust eco system. They need to be its own thing, so it can be used and managed by an individual team independent from any operating system.

  • CameronDev@programming.dev
    link
    fedilink
    arrow-up
    19
    ·
    2 days ago

    Do any serious portable project with C and you’ll see why. You’ll either need to vendor in all the code you want to link against, or you’ll constantly have compilation issues when the OS provided library differs (or doesn’t exist at all) from the one you have on your dev box.

    • one_old_coder@piefed.social
      link
      fedilink
      English
      arrow-up
      10
      arrow-down
      3
      ·
      2 days ago

      Each project would have to reinvent the wheel and make packages for the 10 most popular Linux distributions (every one of them being different, DEB, RPM, Arch, etc.), Windows 10, Windows 11, macOS latest version, macOS previous version, and macOS future version.

      Also you would need 10 virtual machines to test on Linux, 2 virtual machines for Windows, and 3 Apple computers. That would be so easy.

      • KubeRoot@discuss.tchncs.de
        link
        fedilink
        English
        arrow-up
        1
        ·
        51 minutes ago

        Yeah, it’s so annoying how every crossplatform project is having to do that, it’s such a burden on all those indie developers all managing so much hardware and automation to support those platforms. /s

        I think I’ve seen the same argument against Linux package managers in general, and it’s bullshit in the way that it’s not on the projects to package for each distro, it’s on the project to provide a functioning build system, or at least binaries, and from there it’s on the distribution maintainers to figure out packaging.

        But also, in cases where packaging is more complex than just one dependency system for a whole language, it would be beneficial to have one unified system - if all languages are packaged in a unified way for specific system package managers, then you only need to develop a system for them once across all languages, and then you might have one system you need to plug your project into, and from there it could be automatically packaged into all those systems.

      • TrickDacy@lemmy.world
        link
        fedilink
        arrow-up
        2
        ·
        1 day ago

        Haha sure I guess. I think before package managers people used a hodge podge of manual systems to manage dependencies and it sucked. Your way sounds even worse tbh

  • spj@sh.itjust.works
    link
    fedilink
    arrow-up
    9
    ·
    2 days ago

    Reminder that TIOBE is ass and shouldn’t be used for basically anything except for who to target advertising to.