Rust 1.6

The Rust Language FAQ

0.1 Are there any big programs written in it yet? I want to read big samples.

There aren't many large programs yet. The Rust compiler, 60,000+ lines at the time of writing, is written in Rust. As the oldest body of Rust code it has gone through many iterations of the language, and some parts are nicer to look at than others. It may not be the best code to learn from, but borrowck and resolve were written recently.

A research browser engine called Servo, currently 30,000+ lines across more than a dozen crates, will be exercising a lot of Rust's distinctive type-system and concurrency features, and integrating many native libraries.

Some examples that demonstrate different aspects of the language:

You may also be interested in browsing trending Rust repositories on GitHub.

0.2 Is anyone using Rust in production?

Yes. For example (incomplete):

0.3 Does it run on Windows?

Yes. All development happens in lockstep on all 3 target platforms (using MinGW, not Cygwin).

0.4 Is it OO? How do I do this thing I normally do in an OO language?

It is multi-paradigm. Not everything is shoe-horned into a single abstraction. Many things you can do in OO languages you can do in Rust, but not everything, and not always using the same abstraction you're accustomed to.

0.5 How do you get away with "no null pointers"?

Data values in the language can only be constructed through a fixed set of initializer forms. Each of those forms requires that its inputs already be initialized. A liveness analysis ensures that local variables are initialized before use.

0.6 What is the relationship between a module and a crate?

0.7 Why is panic unwinding non-recoverable within a thread? Why not try to "catch exceptions"?

In short, because too few guarantees could be made about the dynamic environment of the catch block, as well as invariants holding in the unwound heap, to be able to safely resume; we believe that other methods of signalling and logging errors are more appropriate, with threads playing the role of a "hard" isolation boundary between separate heaps.

Rust provides, instead, three predictable and well-defined options for handling any combination of the three main categories of "catch" logic:

Cleanup through RAII-style destructors is more likely to work than in catch blocks anyways, since it will be better tested (part of the non-error control paths, so executed all the time).

0.8 Why aren't modules type-parametric?

We want to maintain the option to parameterize at runtime. We may eventually change this limitation, but initially this is how type parameters were implemented.

0.9 Why aren't values type-parametric? Why only items?

Doing so would make type inference much more complex, and require the implementation strategy of runtime parameterization.

0.10 Why are enumerations nominal and closed?

We don't know if there's an obvious, easy, efficient, stock-textbook way of supporting open or structural disjoint unions. We prefer to stick to language features that have an obvious and well-explored semantics.

0.11 Why aren't channels synchronous?

There's a lot of debate on this topic; it's easy to find a proponent of default-sync or default-async communication, and there are good reasons for either. Our choice rests on the following arguments:

0.12 Why are channels half-duplex (one-way)?

Similar to the reasoning about default-sync: it wires fewer assumptions into the implementation, that would have to be paid by all use-cases even if they actually require a more complex communication topology.

0.13 Why are strings UTF-8 by default? Why not UCS2 or UCS4?

The str type is UTF-8 because we observe more text in the wild in this encoding – particularly in network transmissions, which are endian-agnostic – and we think it's best that the default treatment of I/O not involve having to recode codepoints in each direction.

This does mean that indexed access to a Unicode codepoint inside a str value is an O(n) operation. On the one hand, this is clearly undesirable; on the other hand, this problem is full of trade-offs and we'd like to point a few important qualifications:

0.14 Why are strs, slices, arrays etc. built-in types rather than (say) special kinds of trait/impl?

In each case there is one or more operator, literal constructor, overloaded use or integration with a built-in control structure that makes us think it would be awkward to phrase the type in terms of more-general type constructors. Same as, say, with numbers! But this is partly an aesthetic call, and we'd be willing to look at a worked-out proposal for eliminating or rephrasing these special cases.

0.15 Can Rust code call C code?

Yes. Calling C code from Rust is simple and exactly as efficient as calling C code from C.

0.16 Can C code call Rust code?

Yes. The Rust code has to be exposed via an extern declaration, which makes it C-ABI compatible. Such a function can be passed to C code as a function pointer or, if given the #[no_mangle] attribute to disable symbol mangling, can be called directly from C code.

0.17 Why aren't function signatures inferred? Why only local variables?

0.18 Why does a type parameter need explicit trait bounds to invoke methods on it, when C++ templates do not?

0.19 Will Rust implement automatic semicolon insertion, like in Go?

For simplicity, we do not plan to do so. Implementing automatic semicolon insertion for Rust would be tricky because the absence of a trailing semicolon means "return a value".

0.20 How do I get my program to display the output of logging macros?

Short Answer: Set the RUST_LOG environment variable to the name of your source file, sans extension.

rustc hello.rs
export RUST_LOG=hello
./hello

Long Answer: RUST_LOG takes a 'logging spec' that consists of a comma-separated list of paths, where a path consists of the crate name and sequence of module names, each separated by double-colons. For standalone .rs files, the crate is implicitly named after the source file, so in the above example we were setting RUST_LOG to the name of the hello crate. Multiple paths can be combined to control the exact logging you want to see. For example, when debugging linking in the compiler, you might set the following:

RUST_LOG=rustc_metadata::creader,rustc::util::filesearch,rustc::back::rpath

For a full description, see the logging crate.

0.21 How fast is Rust?

As always, this question is difficult to answer. There's still a lot of work to do on speed, and depending on what you're benchmarking, Rust has variable performance.

That said, it is an explicit goal of Rust to be as fast as C++ for most things. Language decisions are made with performance in mind, and we want Rust to be as fast as possible. Given that Rust is built on top of LLVM, any performance improvements in it also help Rust become faster.