Comment by Kranar

3 years ago

Four months to become as proficient in a memory safe, data race safe, and high performance language as in other languages seems like an astonishing accomplishment.

In fact it's frankly unbelievable, I'd have to imagine these guys are coming from a C++ background.

Anecdotally, C++ developers often have a harder time coming to Rust than folks from a more scripty background. They have to unlearn things, and that can be harder than learning things.

You can see similar opinions expressed in this thread, like here, for example: https://news.ycombinator.com/item?id=36496654

  • Python programmers love Rust: - Lots of compilation errors, but then the code does what it says - Fast! That gives an immediate benefit that people coming from C++ don't see.

  • Really? Coming from C++, learning Rust felt very natural and welcome because it put a name and a structure to the mental model I had been using to keep a semblance of sanity while doing C++. Maybe learning primarily with C++11 was a factor?

    • It's a broad strokes kind of thing, not a universal thing. To be honest I think it has more to do with attitudes towards the language and compiler that tend to be more prevalent in C and C++ circles.

      That is, a lot of people expect that the compiler is a tool that must do what they say, not a collaborative partner. Back in the IRC days, people used to join, and be like "Rust won't let me do X. X is obviously okay. How do I get the compiler to shut up and do X?" and the reply would be something like "what if there was another thread? that's what Rust is saving you from" or "Rust's pointer rules are different than the language you're used to."

      Whereas folks from scripty backgrounds don't have preconceived notions of "I should be able to do this in this way," and so tend to trust the compiler more. Heck, that's why a lot of them are learning Rust instead of C; they know the compiler can help them out, and C's compilers cannot to the same degree.

      Now, that doesn't mean that scripty people don't struggle, or that C and C++ developers don't have their own advantages in learning. Just that I don't think it's straightforward to say who has the overall easier time. It's more of a "having learned something like C or C++ does not universally advantage you."

      4 replies →

I don't think it has to be this hard to have memory safety, data race safety, and performance. After building and doing PL design in this space for a decade, I don't believe the assumption that Rust's or C++'s difficulties are inherent.

I think C++ has its own legacy difficulties (which also make transitioning to memory safety tricky), and Rust's choice of borrow checking is only one (sometimes difficult) technique for getting these aspects. But there are almost a dozen other methods out there for getting memory safety besides RC, GC, or borrow checking.

I rather think that these other approaches aren't mature enough yet to enter the mainstream, and we haven't seen them yet.

  • How do you build a data race safe language without taking on the restriction of immutable data (which is imo, a much worse and bigger tradeoff than the borrow checker)?

    I actually really like the borrow checker as a tradeoff, I think it makes code much easier to understand and it makes all aliasing bugs impossible. The removal of aliasing bugs is I think an undersold benefit of using rust.

    • There are a lot of ways, but I think the most promising ones involve regions. We do this a lot manually in Rust, but a language could make this a first class concept. Some examples:

      * Vale combines generational references and linear types with regions to eliminate overhead.

      * Verona lets you divide memory into regions which can be backed by either arena allocation or GC. I think this is promising because for most GC regions you can completely avoid the collections.

      * Cone lets you put borrow checking on top of any aliasing memory strategy, so could be something like the best of all these worlds.

      * No language is doing this yet, but RC plus regions to eliminate the refcounts, then adding in value types for better cache usage, could be a real winner.

      On phone so it's hard to get links, but you get the idea. The nice thing about regions is that they allow composing borrowing and shared mutability, something that the borrow checker struggles a bit with. Regions let us alias freely, and then freeze an entire area of memory all at once. Not that Rust isnt a good approach (it is!) but there are some easier techniques on the horizon IMO.

  • Please demonstrate a practical and memory safe systems programming language without borrowing.

    I'd be delighted to see it, because right now I am not aware of any practical way to have memory safe regions without static tracking of borrowing from these regions. It's either that or runtime checking.

    • This might be of interest: https://verdagon.dev/blog/first-regions-prototype

      It uses region-based static analysis without borrow checking: it doesn't impose aliasability-xor-mutability per object, or even per-region.

      Though, if you'd like to move the goalposts further to no form of borrowing at all, then I recommend looking at languages like Forty2 and Verona, they might be what you're looking for.

      1 reply →