4 ms·
AFAIK the only unique feature of Rust is a borrow checker, right? (compared to other feature-full languages, i.e. not Go) Regarding the main example of author,
by zerr 7y ago
AFAIK the only unique feature of Rust is a borrow checker, right? (compared to other feature-full languages, i.e. not Go)
Regarding the main example of author, it's great that the progressive side of Go team won, so generics are coming in Go 2.
- littlestymaar 7y agoThe “unique feature” thing isn't quite useful when comparing programming languages: the only “unique feature” of a plane are its wings but the implications of having that feature are quite big!
- genuine_smiles 7y agoI’m not away of any language with a feature comparable to its editions. Editions should enable Rust to avoid the bloat of languages like c++, Java, or c# over time while avoiding the Python 2 problem. https://doc.rust-lang.org/edition-guide/editions/index.html https://doc.rust-lang.org/edition-guide/editions/index.html
- pjmlp 7y agoIt still remains to be seen, specially if Rust starts supporting distributing binary libraries, and one tries to compile across multiple epochs with them. Java, C# and C++ control it via compiler flags, and also have the ABI issue across language versions.
- deleted 7y ago[deleted]
- zelly 7y agoYes, I think that's the only new innovation in Rust. Everything else is just an incremental improvement on what already exists elsewhere. Supposedly the developer experience/ergonomics is a feature, but everyone I have met says the syntax is ugly. In terms of ease of getting started and using tooling, it really can't ever compete with the corporate languages like Go, Swift, Kotlin. I can't for the life of me understand why it keeps getting more popular. Memory safety? Security? C++ had the same safety characteristics for at least a decade with dozens of linters and sanitizers on the market, but people never used them or actively turned them off. Rust forces you to use a linter. Maybe it's for the best.
- winrid 7y agoThe syntax is rough mostly because of lifetime specifiers. struct MyStruct <'a> {...
- zelly 7y agoSupposedly lifetime specifiers will be phased out once the compiler gets good enough. I hope so. Syntax matters for adoption.
- winrid 7y agoThat would be amazing. I was really banging my head on that one.
- steveklabnik 7y agoIt's not true. They're required, as they describe programmer intent.
- crispinb 7y agoThough presumably there's a chance that more could be elided over time?
- steveklabnik 7y agoIn theory, maybe.
- Hercuros 7y agoI don’t think they are going to be phased out, since including lifetime specifiers is a means of documenting intent (they are part of a function’s public interface). Removing them would mean that seemingly irrelevant internal changes to functions would cause mysterious compiler errors elsewhere.
- TheDong 7y ago
- awesome_dude 7y agoCan someone explain to me (like a five yo) how the borrow checker is different to Go's -race flag for compilation? Genuine question.
- TheDong 7y agoAbsolutely. The borrow checker in rust has no runtime overhead (whereas go's race flag is runtime only, and has so much overhead you can't turn it on in prod). In addition, the borrow checker catches data races, but it also catches more subtle ownership issues too! For one example of an ownership issue which isn't also a concurrent data-race, let's look at something in go that the -race flag doesn't catch, but that the borrowchecker in rust does: // go b := []byte("foo bar") foo := b[0:3] fmt.Println(string(foo)) b = b[:0] b = append(b, []byte("not foo")...) fmt.Println(string(foo)) // prints "not" // This is because 'foo' is actually "borrowing" // bytes from b, but go doesn't have any way to indicate // that said "borrow" is active, so writing to it might be a bug. That code is here: https://play.golang.org/p/0EK2OzeUG0v https://play.golang.org/p/0EK2OzeUG0v Now let's try to write code that has that same bug in rust: let mut b = "foo bar".as_bytes().to_vec(); let foo = &b[0..3]; println!("{}", String::from_utf8_lossy(foo)); b.truncate(0); b.append(&mut "not foo".as_bytes().to_vec()); println!("{}", String::from_utf8_lossy(foo)); That code is here: https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=8014cbe265ef560048b0315327ca5138 https://play.rust-lang.org/?version=stable&mode=debug&editio... If you try to compile it, you'll see that it doesn't compile with the following error: "error[E0502]: cannot borrow `b` as mutable because it is also borrowed as immutable" In the rust code, the borrow checker keeps track of the fact that "foo" is currently a reference into "b", and because of that, it knows that it shouldn't let the programmer modify the memory out from under "foo". This is just one of many examples I could give, but hopefully it provides some explanation of how the borrow checker is more flexible than just race detection. Basically, there's a lot of cases in programming when it's useful to have a function which takes ownership of an object and turns it into something else, or borrows an object temporarily but then gives back ownership. In languages like go, the fact that "close(channel)" means that the channel can't be written to again is a runtime guarantee. In rust, it can be expressed to the compiler that 'channel.close()' means that channel is gone and using it again is a compile time error. Ownership ends up being a really common concern, and the borrow checker handles it nicely.