The whole point of rusts type system is to try to ensure safe memory usage.
Opinions are opinions, but if I’m letting my runtime handle memory for me, I’d want a lighter weight, more expressive type system.
The whole point of rusts type system is to try to ensure safe memory usage.
Opinions are opinions, but if I’m letting my runtime handle memory for me, I’d want a lighter weight, more expressive type system.
But I don’t think it prevents any more logic bugs than any other type system that requires all branches of match and switch statements to be implemented. (Like elm for example)
I do also believe this might be a sweet spot for a language, but the details might be hard to reconcile.
Edit: I would also prefer shared nothing parallelism by default so the GC can stay purely single threaded.
It isn't though. The whole trait system is unnecessary for this goal, yet it exists. ADTs are unnecessary to this goal, yet they exist. And many of us like those aspects of the type system even more than those that exist to ensure safe memory usage.
I think traits muddy that goal, personally, but their usefulness outweighs the cost (Box<dyn ATrait>)
I should’ve probably said “the whole point of rusts type system, other than providing types and generics to the language”
But I thought that went without saying
It ... just ... isn't, though.
I mean, I get what you're saying, it's certainly foundational, Rust would look incredibly different if it weren't for that goal. But it just isn't the case that it is "the first and foremost goal of every language choice in rust".
I followed the language discussions in the pre-1.0 days, and tons of them were about making it easier and more ergonomic to create correct-if-it-compiles code, very often in ways that had zero overlap with safe memory usage.
Traits don't "muddy that goal", they are an important feature of the language in and of themselves. Same thing with the way enums work (as arithmetic data types), along with using Option and Result for error handling, rather than exceptions. Same thing with RAII for tying the lifecycle of other resources to the lifecycle of values.
The memory safety features interact with all these other features, for sure, and that must be taken into account. But there are many features in the language that exist because they were believed to be useful on their own terms, not in subservience to safe memory usage.
And it's not just about "providing types and generics to the language", it's a whole suite of functionality targeted at static correctness and ergonomics. The ownership/lifetime/borrowing system is only one (important!) capability within that suite.
Lifetimes elision works pretty well so you don't often need to specify lifetimes
It usually pops up when you use generics / traits (what concrete type does it match to?)
Same for Box, but in fact Rust went the opposite way and turfed the Box ~ sigil.
Which I actually feel was a mistake, but I'm no language designer.
Aaaah, I'm realizing in typing this that the `@foo` syntax was actually implemented via reference counting? I think my intuition at the time was that the intention was for those to eventually be backed by a mark-and-sweep GC, which I did think was a poor fit for the rest of the language. But as just a syntax for reference counting, I honestly think it might have been an ok fit.
Or maybe not, I'm ambivalent. But the syntax thing in my comment is more of a red herring for what I think is more of a cultural "issue" (to the small extent it is an issue at all), which is that most Rust projects and programmers seem to try to write in a style that defaults to only choose reference counting when they must, rather than using a style of optimizing them out if they show up in a hotspot during profiling.
Regardless of the specifics here, the same problems apply. Namely that it privileges specific implementations, and makes allocation part of the language.
It wouldn't be a good fit for projects like the ones at Oxide :) I'm very glad Rust itself exists, with good support for use cases like those!