News for hackers. Stuff that matters.
Re:Exploring Rust (from C#) by tomp on Wednesday March 23, 2016 @06:59AM (#11343353)
You're right on the pros but dead wrong (intentionally?) on the cons.

The real reasons it's controversial are: (1) it requires what some people consider excessive amount of annotations for borrowed types, resulting in visual noise, (2) it has an overly restrictive memory safety model (e.g. it prevents concurrent modification, even when provably safe), (3) it claims to be (memory) "safe", but requires (see 2) the use of "unsafe" features for the most basic tasks, such as implementing various collections.

There is other criticism (e.g. allowing overflows), but I think the above is the most controversial.

Re:Exploring Rust (from C#) by Manishearth on Wednesday March 23, 2016 @08:15AM (#11343703)
> the use of "unsafe" features for the most basic tasks, such as implementing various collections.

That's pretty much the _only_ place you need when using unsafe, when implementing "basic collections". The point of Rust's unsafe is to be able to use it to design safe abstractions. This is not a con; this is the _point_ of unsafe.

(Also, one can argue that implementing a collection is not a basic task. It's taught very early on in courses as a way of teaching pointers, but collections aren't simple in general and especially when it comes to memory management. See also: http://cglab.ca/~abeinges/blah/too-many-lists/book/)

> it prevents concurrent modification, even when provably safe

Are you talking about non-lexical borrows here (that will be fixed soon), or about Rust's restrictions in threaded scenarios? You can alleviate some of the threaded restrictions via scoped threads. Most of the non-threaded ones can be fixed (without a performance penalty) using Cell (RefCell for non-Copy types, though there's a slight cost there).

I've been programming in Rust for a while now, and this doesn't turn out to be an issue in practice since the regular way of designing code avoids this pretty well. Programming in Rust as if it was C++ leads to these errors a lot more.

Re:Exploring Rust (from C#) by tomp on Wednesday March 23, 2016 @08:52AM (#11343930)
> This is not a con; this is the _point_ of unsafe.

It's not a con if you consider C; but it most definitely is a con for a language that advertises itself as having "guaranteed memory safety".

> Are you talking about non-lexical borrows here (that will be fixed soon), or about Rust's restrictions in threaded scenarios?

I'm talking about the fact that the programmer has to write the code/algorithms in such a way that Rust's very limited proof engine can handle them. This means using collections in a limited way - if the API doesn't support something, you can't do it (an example would be, splitting a vector and updating each element by a separate thread - IIRC that used to be a problem, maybe it has been fixed already?). This also means implementing concurrent algorithms using the (limited) API (Cells, Atomics, ...) - although that's probably the preferred way in C as well, I'm guessing even things like CAS can be abstracted away with zero cost while improving safety. I'm curious, though, how would I implement the following: I have multiple threads, and I only care about the last result (i.e. they can all write to the same memory location)?

I agree, though, that this is rarely a problem in practice, which is why Rust is an amazing language. The criticism/controversy is mostly coming from outsiders and/or people like me who disapprove of false advertising in principle.

Re:Exploring Rust (from C#) by Manishearth on Wednesday March 23, 2016 @10:15AM (#11344619)
> It's not a con if you consider C; but it most definitely is a con for a language that advertises itself as having "guaranteed memory safety".

I explained in the other comment why this isn't really an issue. Note that most "basic datastructures" exist in the stdlib already, so you don't have to use unsafe code to do this in practice. 100% guaranteed memory safety by your definition is an unattainable goal. In safe rust code you do indeed have guaranteed memory safety, and you're able to extend this by writing unsafe rust code with which you supply your own guarantees of safety.

Safe Rust and unsafe Rust are best viewed as separate languages with smooth FFI between them, see http://doc.rust-lang.org/stable/nomicon/meet-safe-and-unsafe....

> splitting a vector and updating each element by a separate thread - IIRC that used to be a problem, maybe it has been fixed already?

This is scoped threads and is possible. Crossbeam and scoped_threadpool both have solutions for this.

> This also means implementing concurrent algorithms using the (limited) API

That's what you should be doing for thread safety. Like you mentioned, that's what you do in C too. Rust does indeed have CAS atomics.

> I have multiple threads, and I only care about the last result (i.e. they can all write to the same memory location)

This sounds like a use case for monotonic (relaxed) atomic ordering? Not sure.

Note that "the last result" itself doesn't mean anything, due to the way the cache works. There's no global clock (hooray for distributed systems!). The fact that Rust makes you think about this is a good thing. You can stick a Lamport clock in there, but that involves using more atomics and won't be as fast as relaxed ordering.

Re:Exploring Rust (from C#) by steveklabnik on Wednesday March 23, 2016 @10:20AM (#11344669)

  > an example would be
This has not been a problem for quite a while. You call split_at_mut to get two &mut T's back, and then pass them to each thread.
Re:Exploring Rust (from C#) by zerker2000 on Wednesday March 23, 2016 @10:57PM (#11350258)
Non-atomic writes to a single memory location, from what may well be separate cores etc, happen essentially at random due to out-of-order execution. What are the downsides to using the value from the last thread ~spawned~, and calling it a day?
Re:Exploring Rust (from C#) by AlisdairO on Wednesday March 23, 2016 @07:38AM (#11343523)
> (3) it claims to be (memory) "safe", but requires (see 2) the use of "unsafe" features for the most basic tasks, such as implementing various collections.

I think this is an interesting one - implementing collections is (IME) the main thing one needs to use unsafe for in rust. Outside of that I barely find myself needing it at all. Unfortunately, collections are also a go-to intro project for a lot of systems programmers, so I can see how it would be easy to get a bad first impression.

Re:Exploring Rust (from C#) by Certhas on Wednesday March 23, 2016 @07:49AM (#11343572)
The collections criticism is bizarre. How often do you actually have to use "unsafe" in practice? Collections is one example, but it seems to be quite atypical, and not something you'd typically implement yourself.

The argument has always been that it reduces the amount of code you have to check for safety manually. Most of it will be checked by the compiler. Have you run into the problem that most of your code is unsafe?

I've only started dabbling in Rust for some projects, but I've not had to write a single line of unsafe yet, and don't see where that would change.

Re:Exploring Rust (from C#) by tomp on Wednesday March 23, 2016 @08:29AM (#11343796)
> The argument has always been that it reduces the amount of code you have to check for safety manually.

No, Rust's argument is that it eliminates memory unsafety. It even says so on it's front page: "guaranteed memory safety".

Except that it's not guaranteed. It relies on you trusting code that (supposedly) expert programmers have written, and which has been reviewed hundreds of times. Which is no better than C.

I agree that this criticism is mostly a theoretical one; Rust is still a huge improvement (in safety, and probably other areas) over C. But some people (e.g. myself) oppose lies in principle, no matter how well-intentioned they are.

Re:Exploring Rust (from C#) by Manishearth on Wednesday March 23, 2016 @08:36AM (#11343832)
> It relies on you trusting code that (supposedly) expert programmers have written, and which has been reviewed hundreds of times. Which is no better than C.

This is a vast oversimplification.

It relies on you trusting tiny bits of unsafe code which have been carefully reviewed. This is opposed to entire C codebases which need reviewing. It's much, much easier to audit 10 lines of unsafe code than it is to audit an entire application.

The vast majority of Rust code is not unsafe.

Re:Exploring Rust (from C#) by tomp on Wednesday March 23, 2016 @08:53AM (#11343939)
Exactly. Just as I've written in my post:

> Rust is still a huge improvement

> Except that it's not guaranteed

Re:Exploring Rust (from C#) by Manishearth on Wednesday March 23, 2016 @09:25AM (#11344155)
You will never be able to get both 100% guaranteed memory safety and low level control/performance. Opposing it based on principle means that you'll never move on to anything better because a perfect solution doesn't exist.

For what it's worth, you can write quite a lot in 100% safe code, such that you have to trust only the standard library. Which is the case for any programming language.

So, the argument on the front page is true. It does guarantee memory safety in safe Rust code, as much as possible. It gives you the tools to extend your abstractions with unsafe Rust code, which you need to supply your own guarantees with.

Re:Exploring Rust (from C#) by kazagistar on Wednesday March 23, 2016 @02:55PM (#11347209)
> You will never be able to get both 100% guaranteed memory safety and low level control/performance.

Sure you can. You just need a full fledged proof engine instead of "merely" a type system.

Re:Exploring Rust (from C#) by scott_s on Wednesday March 23, 2016 @05:30PM (#11348416)
Since tomp objects to trusting code, then I agree with Manishearth: if you're never willing to trust code, then you can never have guarantees. Even the proof engine is trusted code.
Re:Exploring Rust (from C#) by tomp on Wednesday March 23, 2016 @06:38PM (#11348841)
Well, you have to trust something... Silicone manufacturer, CPU designer, the OS, the compiler...

But the big difference is, if I can do proofs and the compiler breaks my trust, that's a bug in the compiler. On the orher hand, Rust disallows complex proofs entirely, so I have to use unsafe code and trust random humans!

Re:Exploring Rust (from C#) by Rusky on Wednesday March 23, 2016 @09:48PM (#11349978)
The compiler is just as much written by random humans as anything else.
Re:Exploring Rust (from C#) by elcritch on Wednesday March 23, 2016 @05:57PM (#11348599)
This. There's no reason the smaller bits of `unsafe` code couldn't be verified with a proof system (ala COQ). Very few systems can be completely `true` in a mathematical sense, including math itself. IMHO, this is a self-defeating argument. E.g. a form of: "math isn't provable so math sucks!".

In the long run, this viewpoint would prevent moving to a system with 5% unsafe/95% safe which could be much more readily proofed using COQ since only a handful of unsafe code needs to be analyzed – I'm assuming proofing code has exponential complexity growth. So basically give Rust 10 years and I bet someone could build a verified stdlib & compiler for Rust!

Re:Exploring Rust (from C#) by Manishearth on Wednesday March 23, 2016 @09:23PM (#11349868)
This is already being worked on http://plv.mpi-sws.org/rustbelt/
Re:Exploring Rust (from C#) by elcritch on Sunday March 27, 2016 @03:33PM (#11371162)
Fantastic! Rust keeps getting better... Didn't realize Max Planck institute had a software division. Are you familiar with the state of their progress? I've been wondering when/how people might start applying monads to analyze shared imperative state. It appears to be somewhat of the approach in `Iris: Monoids and Invariants as an Orthogonal Basis for Concurrent Reasoning` paper listed. Going to have to keep an eye on these folks.
Re:Exploring Rust (from C#) by Manishearth on Wednesday March 23, 2016 @05:00PM (#11348183)
Well, ok. I guess that's too heavyweight, though.

However, http://plv.mpi-sws.org/rustbelt/

Re:Exploring Rust (from C#) by Rusky on Wednesday March 23, 2016 @12:39PM (#11345999)
Even if the language pulled some magic trick where it could verify collection implementations without unsafe, all you'd have done is move the unsafety into the type checker and compiler backend.

The only difference is that Rust 1) moved some of that into the stdlib and 2) lets third parties extend it to provide more guarantees.

Given this, I think you're drawing a rather arbitrary line- Rust (the compiler + stdlib, optionally + other libraries wrapping unsafe) does guarantee memory safety, full stop. Whether the guarantees are provided by the stdlib or compiler is irrelevant.

Re:Exploring Rust (from C#) by tomp on Wednesday March 23, 2016 @06:41PM (#11348867)
It does guarantee memory safety... until you need to write your own collection. Then it explicitly endorses unsafe code (as opposed to offering a more powerful proof engine). I'm find with trusting something (compiler, proof engine, stdlib), but the issue is that safe Rust is barely a complete language!
Re:Exploring Rust (from C#) by kibwen on Wednesday March 23, 2016 @08:10PM (#11349488)
This is a strange argument. The `unsafe` keyword only lets you do the following: dereference unsafe pointers, call unsafe functions (which usually either dereference unsafe pointers themselves, or are just wrappers over C functions, which are obviously unprovable), and mutate static data. Saying that safe Rust is "barely complete" is just as good as saying that Python is "barely complete" due to the fact that it doesn't allow you to read arbitrary locations in memory.