1. 18
  1.  

  2. 17

    I think the article would benefit from answering the question “why not use the approach that the Maven ecosystem used successfully for the last 10 years?”.

    Regarding immutability: The only reasonable scope of immutability is to record a fact of the past, e. g.

    • Version 1.0.0
    • of crate foo
    • in namespace example.com
    • has been released on 2012-09-12T12:34:56
    • by someone who could prove ownership over that domain at that point in time.
    • Here may be the artifact, if it hasn’t been removed by legal requirements.

    Anything expecting more than that is based on a belief in some platonic immutability that is guaranteed to fall apart on the first cease&desist letter.

    Nitpick: Under the heading Identity the formatting of the list seems to be a bit off.

    1. 13

      Note this is about crates.io, not Rust. You could write a package repo separate from crates.io that has namespaces and it would work just fine. Its a policy decision, not a technical one.

      1. 15

        I think it’s about Rust in so far, as that cargo and rustc ship together, so expecting people to start using a different repository with a different dependency resolver than cargo, is a tough requirement.


        To be honest, this gives me Go generics vibes all over again:

        People spending years on explaining why it’s not necessary, why no off-the-shelf solution could possible work, how 20 years of experience with existing designs doesn’t translate to Rust, inventing all kinds of crazy design requirements that proposals must fulfill …

        In the end Go people hired Wadler, who built the most basic and straight-forward generics design in a minimal amount of time, just as many people suggested from the start.

        Will Rust repeat this time-consuming mistake?

        1. 5

          That’s fair, I just wanted to draw a line between Rust-the-language and Rust-the-system. I don’t expect people to use a different repo, just pointing out that it’s possible if people want to work on it enough. It’s not even conceptually hard:

          Reserve __ as a path separator, and you can make a crates.io-compatible repo that enforces namespaces in the form of user__cratename, or path1__path2__path3__cratename. That will give you package names that work transparently with existing tools, and breaks a grand total of about three existing crates, none of which are major ones. Once that repo exists as a real thing, you can probably ask the crates.io team to reserve __ on crates.io and disallow new crates from including it, so package names won’t clash with each other (ie, you won’t have the package icefox__foo on my-namespaced-repo and an entirely separate package icefox__foo on crates.io).

          It’s a hack, but it would work just fine, and require no changes to Cargo or Rust itself. I keep waiting for someone to actually try this and it hasn’t happened yet, kinda annoyingly, and I don’t care enough to make time for it. On the other hand, crates.io hasn’t imploded into a cesspit of abuse and uselessness yet either, last I checked, though it’s been a long time since I poked around in the working group chat to see what the admins think of it.

          Hence why I wanted to distinguish Rust-the-language from Rust-the-system. Unlike Go, where PR’s are going to go through Google and have to work with existing and future programs, you need zero buy-in from Rust-the-language to make this work, and extremely minimal buy-in from Rust-the-system to make this work robustly. Crates.io is just a website, and Cargo has support for different repositories.

        2. 5

          I really want to agree with you, but the author of the post saw it fit to call it “no namespaces in Rust” and not “no namespaces in crates.io”.

          1. 3

            Yeah, but they then talk about crates.io the whole time?

            1. 3

              it is indeed baffling, almost like they can’t really fathom an alternative to packaging for Rust

              1. 4

                Hence why I make sure to point out the difference.

        3. 10

          It’s also an example of XY problem. Package namespaces are one possible solution out of many to a number of different problems, such as:

          1. guaranteed availability of certain package names (owner-prefixed names in this case) to mitigate squatting,
          2. tying of package name to owner identity, making the owner more prominent, to help users recognize which crates are “official” and which ones are by unknown strangers,
          3. grouping of multiple packages together for ease of discovery.

          These could be conceivably solved in other ways. For example, nothing stops crates.io website from making crate owners more prominent (it could even display them as literally owner/crate), and showing some kind of official/verified status for major crates (e.g think how Play Store shows app developers, or how Twitter has verified users).

          Crates.io could give projects dedicated sections on the website to list their own groups of crates.

          Squatting can be reduced with spam reporting functionality and a banhammer. Most typosquatting could be prevented with a bit of levenstein-like name checks before publishing, or a “did you mean?” in cargo add.

          cargo add owner/crate can be implemented today. There’s an API for checking the owner. Owner name doesn’t have to be repeated over and over again throughout the code.

          There are also package aliases. If you want namespace/package to be usable as bare package in the code, it is doable with aliases foo = { package = "someprefix-foo" } in TOML, [lib] name in the crate, or use statements.

          crates.io could “pave the cowpath” of using prefixes for project names, such as tokio-* and allow owner of tokio crate to reserve all of tokio-*. That’s just an extra server-side check and it doesn’t require any language changes or rift in the whole ecosystem.

          I’m not saying these off-hand suggestions are in every way better than namespaces, but namespaces aren’t the only way forward, and namespaces have their own downsides too.

          1. 4

            Squatting isn’t the only problem the namespaces would solve. It would also allow a ‘literal names policy’, like Elm has: https://discourse.elm-lang.org/t/literal-names-policy-i-e-how-to-name-packages/242

            Literal names would massively increase discoverability of packages.

            Out of your suggestions, I like ‘pave the cowpath’ best, it still doesn’t solve the problem mentioned in the article. In fact, as far as I can tell, nothing would, short of closely tying crates and Rust packages together.

            1. 3

              For discovery Cargo has categories, keywords, and descriptions. I’ve tried to improve that with https://lib.rs

              I get that clever punny names are hard to recognize, type and memorize. But adding namespaces makes that worse, because the crate names will commonly contain usernames. People’s nicknames are unrelated to crate’s functionality, and even likelier to be twisted in order to be unique.

              I can ask people to choose boring English crate names, but I can’t go around telling people they should have names that are easy for me to spell :)

          2. 10

            Supporter of language L with a misfeature F: “F is actually a good thing!”

            They could have best of both worlds: namespaces for the cutting edge fast dev and forks, upper level namespace (with some bureacracy to protect it from immaturity) for semi-official crates.

            1. 2

              But for cutting edge dev and forks, there’s pulling deps directly from git repos.

            2. 5

              As a Rust outsider, I don’t quite understand the claims here.

              It seems that all three features could exist equally well with namespaces, though it may be a bit easier to implement and maintain them without.

              1. 4

                “namespaces” is so overloaded. If you have names, you have namespaces. It’s just about how you the human choose to interpret those names, and in some cases how the machine shows the names to the human.

                “There is already a {package, class, object, data element} named foo, and someone else also has something of the same kind named foo! If only I could name it {com.example}foo !” Name it “com.example.foo” or “com_example_foo” or whatever your naming system allows. It’s exactly the same thing.

                1. 2

                  If I can own all packages under the namespace cmcaine, for example, that has different UX for my users than just naming all my packages cmcaine_blah because it makes the ownership of/responsibility for the package very visible. Namespaced packages can also be more or less ergonomic to use based on decisions by language and tool developers’ choices.

                2. 2

                  My counter to this whole point: if we’d had nested namespaces from the get go, I very much doubt anyone would be arguing seriously for abandoning them in favor of creating a strong perverse incentive towards name squatting. Which, if we’re being honest, was and is the inevitable outcome of a flat namespace policy for any language that attains market success.

                  1. 1

                    Totally correct. Though a counter argument is that Rust made the terrible mistake of migrating generics syntax from the (correct) [] back to <>.

                  2. 2

                    This evokes the question: why centralize at all? Why not just pull from git repos?

                    Avoiding typing the github.com prefix seems like not a big deal considering the sorry state of package management in C/C++.

                    1. 4

                      Why not just pull from git repos?

                      Because you want a guarantee that some release is as immutable as humanly possible, not a git rebase away from being changed after the fact.

                      not a big deal considering the sorry state of package management in C/C++

                      I think C/C++ should serve as a point of comparison for exactly nothing.

                      1. [Comment removed by author]

                        1. 0

                          I don’t think Rust is that great – it’s simply the bare minimum that should be acceptable today.

                          Writing C/C++ for any device with internet access should get people’s programming license revoked for gross negligence.

                          1. 2

                            This is a bit hyperbolic (particularly the bit about revoking people’s programming license - I’m firmly against the sort of professionalization of programming as a profession that would lead to the existence of legally-significant programming licenses). But the fact is that that there have been decades of software written in C and C++ that have pervasive memory safety vulnerabilities that can be exploited by making malicious network requests to the devices they run on. Pervasively using languages at all levels of the stack that minimize memory safety vulnerabilities, including but certainly not limited to rust, would go a long way towards reducing the risk of malicious hacking of internet-connected devices.

                            1. 0

                              I think you do have to learn about C and the history of some of this stuff in order to make those improvements well. And I don’t think it should be based on fear / dogma statements; because that’s not a good starting place for creative activity, or for making engineering decisions. It’s important for new generations of programmers to learn the ins and outs of C, so that they can then do the right thing (which may involve wrapping it in Rust or writing own device drivers or really whatever; there’s a boundary). And a lot of times, to learn you actually do need to practice, which could include practicing by writing C programs that run in environments where they would not “harm” anything.

                              But I feel like communicating to people that they should be afraid of writing C in this way from such a position, and making them feel bad for it, is kind of disempowering to them. The hardware is also ultimately an open memory access machine (with layers of protection, for sure), and someone needs to learn and understand that. We don’t have the dream safe machine yet. I don’t want people that are learning these things to feel like they are doing something bad because they keep coming across comments from internet strangers that mock these technologies and yell at them from some high horse. Making a game in C and trying it in WASM won’t have you bring the internet down. I also think we need to wait and see how things in the new languages and frameworks play out.

                              1. 2

                                It’s important for new generations of programmers to learn the ins and outs of C, so that they can then do the right thing (which may involve wrapping it in Rust or writing own device drivers or really whatever; there’s a boundary). And a lot of times, to learn you actually do need to practice, which could include practicing by writing C programs that run in environments where they would not “harm” anything.

                                I’d say it’s important for new generations of programmers to learn how computer hardware actually works with a minimum of abstraction layers between their code and the hardware. This isn’t the same thing as learning the ins and outs of C, and in fact one of the things that I think is important for programmers to write bare-level code to learn is precisely that C is not the only possible tool you can use to directly control hardware.

                                C is a language that can produce a binary executable with a minimal runtime, so is Rust, and in principle you could write your own compiler for your own language that does this too if you spent enough time on it. It happens to be very widely used in that problem domain, but that’s just a contingent fact about how programming developed. C was designed at a particular point early in the history of programming, it is flawed in many ways that are incidental rather than essential to the job it needs to do, in ways that make it harder than necessary to write correct and maintainable code.

                                But I feel like communicating to people that they should be afraid of writing C in this way from such a position, and making them feel bad for it, is kind of disempowering to them. The hardware is also ultimately an open memory access machine (with layers of protection, for sure), and someone needs to learn and understand that.

                                People shouldn’t be unduly afraid of writing C, but they should be aware of the ways it is possible to write non-obviously buggy code in C that makes network-connected C programs liable to bugs, particularly security bugs, that might allow malicious network users to do unpleasant things to computer systems with C programs running on them. Certainly programmers who are writing in C should be aware of how their own C programs can be buggy, so they can use tooling and best practices to mitigate this - and it’s also a good engineering reason to consider writing a program in a language other than C.

                                I don’t want people that are learning these things to feel like they are doing something bad because they keep coming across comments from internet strangers that mock these technologies and yell at them from some high horse. Making a game in C and trying it in WASM won’t have you bring the internet down. I also think we need to wait and see how things in the new languages and frameworks play out.

                                As a meta-point, I would like people who are learning things to absorb the point that just because an internet commenter mocks a technology, doesn’t mean that technology is always bad for all use cases - even if that commenter was correct about the things they mocked. And yes people should absolutely have the freedom to write whatever code they want on their own software. I should be able to write a program in C on a Raspberry Pi that responds to any network request with my full name, address, and social security number and put that on the public internet, if I want.

                                Anyway, I’m currently writing this comment on an x86 laptop running Linux (with a kernel of millions of lines of C! And hundreds of thousands of lines of C in systemd!), using Firefox (with millions of lines of code in C++!). I’m not advocating that software developers should have a blanket policy of not writing C or C++ on internet-connected computers. I’d rather the linux kernel exist than not exist because Linus Torvalds thought it was wrong to write a kernel in C in 1993. But memory safety vulnerabilities are real, and even apart from this more modern languages are generally more pleasant to program in than C, and I would in fact encourage new programmers (as well as old programmers!) to seriously consider whether it is possible to avoid writing new code in C (or replace existing C code with non-C code), as they go about creating and maintaining computer programs.

                                And if anyone reading this comment does happen to be a newbie programmer just learning C, everything I wrote is intended for your eyes, just as much as it’s intended for anyone else who read this thread.

                                1. 0

                                  These are all good points, and I agree with them all, basically. It’s just that, it seems like we are not yet at a place where it’s clear enough that any one such language reduces these bugs enough in practice, to be able to actually make strong decisions. The same is always said of static typing vs. dynamic langs, yet I don’t find that programs are necessarily any less or more buggy based on the current fashionable language in said decade.

                                  Given that it’s not that clear yet, you definitely have to actually learn both C/C++ and Rust in order to decide on either side based on smaller tradeoffs. Another aspect is that there’s just a lot of cases where C may actually fit better, like if you just think it’s easier to use (esp. if you already know it) and want to make some game that runs in a sandboxed WASM context and are fine with memory bugs (scoped to just your game) within the sandbox. And the sandbox has no bugs because it’s written in Rust. Or, that the next language that takes us beyond these things is in between C and Rust more, like TypeScript is to Javascript (vs. attempts like Elm that didn’t take off). Cyclone did some of this, but not with as strong an org and community backing it as Rust, and also kind of academic. Some folks are trying to do lifetime analysis in C/C++ too. And I don’t think “provable” safety based on types is enough: for security you always just need to test strictly. So if testing is really the only way to be sure, maybe less sound type stuff but better test results is a fair tradeoff. So the decision comes down to: did Rust make us do better on these tests. And the tradeoff will vary across different types of software. Like for console games vs. for OSes vs. for language VMs vs. network drivers…

                                  Anyways generally speaking, I think it’s not stretegically strong enough to disinvest in actually practicing writing C/C++ yet, so I find it out-of-place to discourage people from practicing it to this degree, I guess, because it feels disingenuous. And there’s a lot of other types of software out there than just the network drivers and OSes people pick on. Like generative art. Maybe C’s memory glitches create better glitch art, when you make a WASM glitch art VM like PICO-8, who knows?

                            2. 0

                              I’ll take that as a “yes.”

                              1. 0

                                It’s 2020, I really don’t care.

                        2. 2

                          Because crates.io is designed to be permanent, as much as is feasible, to avoid things like The Great Left-Pad Incident.