Hacker News new | ask | show | jobs
by Animats 4155 days ago
Wow. I wrote that article on LtU last night, after going over there to see what the language theorists were saying about Rust. (And after, for the third time in three weeks, having my Rust code fail to compile because the Rust crowd changed the language again, after the "alpha release" and its claims of stability: http://blog.rust-lang.org/2014/12/12/1.0-Timeline.html) I wasn't expecting it to be picked up on Hacker News.

Rust is going to be very important. The ownership system is a major step forward in language design. It's a huge improvement over C/C++.

It's not easier to write than C++. Rust may feel clunky for people coming from Javascript, Python, Ruby, and PHP. Having to think about lifetime issues for mere strings is a new cognitive load. The big win with Rust is that most of the errors are caught at compile time. This is Rust's big advantage, but alien to scripting programmers. The Rust compiler report errors in three phases. First you get all the syntax errors, and until the syntax is perfect, that's all you get. Then you get all the type errors, and until the type issues are perfect, that's all you get. Then you get the ownership errors. Ownership is a global analysis; ownership problems involve at least two points in the program. The compiler produces good, but very wordy error messages. (Hint to Rust developers: put in a line length limit and word wrap for long compile time error messages.) If your ownership design is faulty, the result is likely to be "fighting with the borrow checker", because the problem isn't local, and just fixing the compiler-reported error will make the problem pop up elsewhere. The cleverness of the ownership system is impressive, but some programmers are going to feel like they're being hammered by it. Successful C++ programmers won't have a major problem with this. It may be tough on the Javascript crowd.

Rust requires some advance planning, which may be incompatible with "agile" development. It's also difficult to port code from other languages to Rust without rethinking the ownership and bounds logic. There is a port of Doom to Rust. It has a lot of unsafe code, because Doom's internal memory structures are not directly compatible with Rust's. Such problems will recur as big packages with delicate internals are ported over to Rust.

This is partly a documentation problem. The current tutorial (http://doc.rust-lang.org/book/hello-cargo.html) is relentlessly upbeat and glosses over too many of the hard problems. Once some third-party books have been written, that situation should improve.

3 comments

Not easier than C++? I dunno, C++ looks like a clusterfuck of complicatedness. I'm mostly coming from F#, with some C. Rust's ownership system just makes sense and seems to perfectly answer the questions I have when using C APIs. Rust, for me, looks a lot like what I've wanted when writing performance F#. I'd commit atrocities to have optional ownership in F#.

Every time I've fought with the borrow checker, it's because I've had a serious design or conceptual flaw. (Well, apart from syntax/compiler questions). Since you can derive most of the rules just by thinking about it, I find it grows on you quickly. I'll be very saddened if the borrow checker actually ends up being hurtful for adoption overall. Though I agree if you cannot handle pointers or think about memory, Rust will be difficult. So yeah, scripting only devs will have trouble. But! It's better than them writing the code in C.

Rust overall seems like that. There's less random stuff and things work mostly by thinking about safe, zero overhead abstractions, and what falls out from those mandates. Mostly.

Now, maybe if I was a modern C++ programmer, I'd find the effort about the same. OTOH, C++ systems don't end up as safe as Rust ones, so I'm not sure there's a perfect comparison to be had. Maybe that'll change as C++ has started catching up feature wise, but someone I doubt it.

Overall, I think Rust is easier to use than C++ but not easier to write than C++. Writability is a specific facet of usability, which is hurt by strict upfront checks.

Writability is a worthy thing to improve: GHC's -fdefer-type-errors feature is a good example. I hope Rust improves its writability in the future.

I think just like other languages, writing Rust leads to a familiarity with what the compiler wants. Then you spend more time thinking about design and the problem at hand, and less fighting the compiler. I think Rust will ultimately be easier than C++ to write because while there are tricky concepts to master, there should be much fewer of them than C++ has.
I disagree. While you get familiar with what the compiler wants (certainly I did, after using Rust for more than 2 years now), it's just that Rust compiler wants more from you than C++ compiler does.

The number of tricky concepts largely do not affect writability, because you don't have to use them. The number of mandatory compile time checks do, because you have to pass them.

One way to improve writability is a mode to turn off some of checks while you are exploring. I already gave a good example from Haskell. When you are done exploring, you can turn on all the checks.

Hmm, so like a Rust flag like --allow-leaks or --corrupted-ownership?

It seems like editor support would totally dominate here. That is, realtime checking of lifetimes and autocomplete/inline errors should be a much bigger improvement in write times than some way to emit invalid code.

Thank you, you've managed to nicely express my feelings on Rust. For coming up with a polished end product that works, Rust is easier, but for bashing on your keyboard to get out your ideas it can be a little frustrating compared to even C++.
Just a historical note: Rust's ownership system has much historical pedigree, such as the Cyclone language and the work on ML compilers with region inference, following Tofte and Talpin's pioneering work. The Wikipedia article (https://en.wikipedia.org/wiki/Region-based_memory_management...) has a good overview.
I know, I wrote one of the early papers: Strict Mode for C++ (2001): http://animats.com/papers/languages/cppstrictpointers.html Further back, Ada has region-based memory allocation.

Around 2002, when there was concern about computer-related terrorism, I suggested that the C++ standards committee's unwillingness to deal with memory safety constituted material support of terrorism. They were angry, and terrified. That post was actually deleted from their USENET group.

Although as a long-time C++ programmer I'm the first to criticize it when it deserves it, that's a pretty assholish thing to suggest. As if we needed more decisions being made by fear instead of logic around that time.
> memory safety constituted material support of terrorism.

I love this. Not the terrorism charge per-se, but the general idea. Using unsafe code should be shunned, in general. After Rust 1.0 or so, any new C projects, especially for people not heavily invested in C, should be met with questioning.

I'm looking at this one project, mostly PHP. But they need some socket and packet handling, and they wrote it in C. Complete with lines like:

  thing = malloc(somesize); // gets memory
  ...
  free(thing); // give memory back
And network-connected string parsing galore. Or a million line project, used in many networks, compete with its own hacked up XML processor, that has never issued a security advisory. I'm looking forward to a time when the choice to use C here would be questioned and viewed with a doubtful eye by everyone.

Propaganda similar to "loose lips sink ships", aimed at memory unsafe code, might help achieve that goal.

I had no idea that Ada has regions. The Wikipedia article doesn't mention it. Maybe somebody who knows about it wants to edit the article?
I agree with many of your points actually. But I wrote the Doom renderer in rust at https://github.com/cristicbz/rust-doom and it's not a port, it's written from scratch based on specs, so maybe your argument is correct in general, but it really doesn't apply to it: it has very little unsafe code, some which really shouldn't be:

1. A tiny function which loads textures. I was fooling around with optimising load speeds. The actual speedup I got was insignificant and I really should revert it to safe code.

2. A silly getter on the transformation matrix---another misguided attempt at a speedup; no reason to use UnsafeCell instead of RefCell. Should revert.

3. Casting buffers from files as structs. This is safe for any buffer the same size as a Copy struct, std offers no such function, so I do. Unsafety is isolated in two small functions (one for T and one for Vec<T>), all its callers are safe.

4. Interacting with OpenGL. Fair enough, this happens all over the place, but it's not actually unsafe. The OpenGL bindings library didn't take much care to only mark unsafe operations as such, and all GL calls are marekd unsafe---which is why I wrap them up in a macro which peforms the operation in an unsafe block and panics on any error. I should port my code to glium and then this would go away as well.

*better formatting