
Rust in 2016 - aturon
http://blog.rust-lang.org/2015/08/14/Next-year.html
======
fpgaminer
I had the opportunity to work with Rust >1.0 recently, implementing an image
processing algorithm. Knowing that the compiler was looking out for me, a
wingman of sorts, was quite the pleasant experience. When coding in C I have a
very paranoid mentality, constantly questioning every line of code and its
impact on program state/memory. It results in my C code being almost always
free of memory related bugs, but the work is absolutely _exhausting_. Rust was
great in this regard, dramatically reducing the amount of mental capacity
expended while coding. Either the compiler would catch the bugs, or worst-case
a run-time assert would catch it and point me directly to the problem.

The major criticism I came away with, due in part to the type of program I was
coding, was for Rust's lack of implicit type casting (more specifically,
widening). What I mean is, adding a u8 and a u16 is an error in Rust. Rust
will refuse to implicitly cast the u8 to a u16. These situations came up very
frequently while implementing my program because I had to do a lot of
optimized, low-level math. The scattering of type casts throughout the program
resulted in clutter without any obvious benefit.

When I looked into the problem, the arguments I saw against it were often
explanations that Rust is meant to be explicit and non-magical. But Rust, for
example, already has type inference which I classify as "magical". Implicit
type widening is hardly magical. And I don't see how it would be confusing or
result in bugs, as long as only safe widening is done implicitly.

I think those involved in the Rust project were just scared off from it
because of C's bizarre implicit type casting rules which result in bugs for
typical programmers. I can understand that, but it's not like it can't be done
better in Rust. Besides, if Rust is meant to be a system programming language,
won't math between differing types come up often? And wouldn't handling those
cases gracefully be a boon to productiveness in Rust?

~~~
kzrdude
How to address this problem?

    
    
        fn foo(x: u32) { }
        let x: u16;
        let y: u16;
        foo(x * y);
    

`x` and `y` would have to be multiplied before they are widened to `u32`. This
creates an overflow bug that may only be visible in the released code (release
mode has arithmetic overflow checking off by default).

~~~
jcranmer
A smart solution could be to have arithmetic operators automatically coerce
the types to the type of their result, if the result type is already known.

~~~
fpgaminer
Indeed, that is my intuition as well. This is the safest default behavior from
the compiler, and even solves crazy expressions like:

    
    
        u64 = ((u8 + u16) * u32) / u8;
    

It's hard to reason about what a programmer would want that statement to do.
Coercing everything to u64 is the safest option. The idea, though, is to allow
the programmer to use explicit casts to define exactly what they want when the
need arises. So:

    
    
        u64 = (((u8 + u16) as u16) * u32) / u8;
    

Would mean u16 addition, u64 multiplication and u64 division. So you get the
benefit of safe, implicit type widening without losing the ability to micro-
optimize when you want to.

~~~
arielby
The annoying thing is that (because of type inference) parts of the expression
could be within different expressions:

    
    
        fn required_bytes(width: u16, height: u16) -> u64 {
            let size = width * height; // what's the type of size?
            size + 12
        }

~~~
fpgaminer
True, type inference would make an ideal solution difficult. But I'm totally
fine with the compiler failing to apply implicit casting when type inference
is involved. This code is just as readable, if not better:

    
    
        fn required_bytes(width: u16, height: u16) -> u64 {
            let size: u64 = width * height;
            size + 12
        }
    

I just really don't want to have to write this all the time:

    
    
        fn required_bytes(width: u16, height: u16) -> u64 {
            let size = (width as u64) * (height as u64);
            size + 12
        }

~~~
echaozh
If there is a type inferred, single character operator which can cast one
numeric type to another, both sides can be happy.

~~~
xyproto
This way of thinking leads to ASCII spaghetti as features are added over time.

------
saosebastiao
I would easily pay 3x the Xamarin price for a Xamarin-like platform for Rust.
And I'm pretty sure I'm not alone.

It's the perfect language for a mobile platform, and I would love to use the
zero-runtime-cost abstractions without resorting to the C++ hand-grenade
roulette. The fact that it has an ML heritage, with all the goodies that
entails (ADTs, pattern matching, type inference, etc), is even better.

~~~
moonchrome
I think people overestimate Rust as an application programming language.

It has some nice features but at the end of the day their focus is safety
above all else - this actually creeps up all over the place - requiring you to
be explicit, APIs requiring you to deal with every possible error type (even
the ones you don't really want to deal with), etc. Error handling was still
very messy last time I checked.

You know what makes you productive with high-level (often dynamically typed)
languages ? Optimistic programming - you write some code and do the least
amount of work to run it and see how far it gets you. Maybe a part of it fails
under some condition, maybe some default assumption turns out to be wrong,
etc. ... You can live with that because you got something working in fraction
of the time it would require you to handle all the edge cases and type out all
the bits and peaces up front. The sooner you get to run the sooner you get to
iterate.

And that's ignoring the cost to iteration time because of compile time.

Rust has it's design goals - it's trade-offs are decent for the context they
are made in - but it isn't my idea of high productivity application
programming language.

~~~
saosebastiao
My very first use case for rust was to replace a ruby script that was running
too slowly. The script did some free form text parsing and mathematical
postprocessing, and then dumped out a huge load file for SQLite. It took me
much longer to initially write than the ruby script...but after throwing in
all the debugging and error handling after the fact with the ruby script, I
spent about half as much time writing it in rust. And that was with 2 years
experience with Ruby and zero experience with rust. There is a lot to be said
about a language that is strict, strongly typed, and with an emphasis on
safety. If I'm shipping a product with my brand name attached to it, I would
so much rather catch easy bugs at compile time than run time.

~~~
bpicolo
There are higher-productivity, strongly/statically typed languages out there
that are probably more reasonable for typical applications programming

~~~
saosebastiao
With rust though, you get two things that you can't with the other
strong/static languages: 1) extremely low resource usage (very helpful on a
phone/tablet with limited resources), without an embedded runtime, and 2)
native portability almost on the same level as C/C++.

I admit, I have higher productivity with Scala and F#, but the productivity
gap isn't insurmountable. The borrow checker isn't a huge problem once you get
used to it, and that seems to be the biggest hurdle that others have. The
biggest thing I find lacking in rust is a compelling asynchronous IO solution.
I would love an async/await capability, or even better, something along the
lines of F#'s computation expressions. Mio is making progress, but is
extremely immature in comparison.

------
endgame
How is nobody talking about push-button cross-compilation? It could be huge!
The only language that I'm aware of that does it at all well is C and that's
because the only build tool that does it at all well is automake. But even
then the library situation is very hit-and-miss. If rust nails this it's going
to be awesome.

~~~
chimeracoder
> push-button cross-compilation? It could be huge! The only language that I'm
> aware of that does it at all well is C

I'm not familiar with the term 'push-button', but Go also does cross-
compilation very well.

(In fact, on Go, technically _all_ compilations are cross-compilations; it
just happens that the target platform and architecture may match the platform
and architecture of the current machine.)

I'm not sure if that's still the case in 1.5 onwards, since I know they
changed some stuff to make it even easier to target other platforms and
architectures, but it was the case previously.

~~~
Manishearth
I'm pretty sure that the range of platforms for which Go does cross
compilation "very well" is quite small. Go has a sizeable runtime, and you
need to have a version of the runtime that works on each platform (for exotic
platforms you would probably have to write some of the building blocks from
scratch). This isn't push-button, this is just "the distribution supports many
common platforms"

For example, it seems like compiling to MIPS is not push-button for Go. On the
other hand, Rust supports all platforms that LLVM supports, though you need a
version of the stdlib compiled for that platform (you don't have to write any
code like in the Go case, you just have to compile the sources with the right
invocation). For push-button compilation, we just need to distribute these
binaries.

~~~
tomp
> I'm pretty sure that the range of platforms for which Go does cross
> compilation "very well" is quite small

Given that the number of popular platforms is approximately 2 (Intel and ARM),
I don't see that as a huge problem.

~~~
pcwalton
Well, the OS and bit width matters too. {x86-32, x86-64, 32-bit ARM, AArch64}
on {Windows, Mac, Linux, Android, iOS} ends up describing a decently large set
of targets.

Also, you'd be surprised how often people request minor platforms. It's enough
that we regularly get people asking for a C backend because they only have a C
compiler for that target (though I think a C backend ends up usually not being
what those people actually want).

~~~
tomp
Hm... I probably don't know enough about compilers, but why does
Windows/Mac/... matter for a _compiler_ (I see why it would matter for the
_standard library_ )? AFAIK, the main differences between these platforms are
calling conventions (and possibly exception mechanisms), which LLVM should
abstract away.

~~~
pcwalton
You're missing at least (a) structure padding/alignment; (b) debug info; (c)
name mangling. LLVM abstracts over some of the differences but definitely not
all.

In any case, just having a Rust compiler isn't very useful; you need a
standard library (or at least libcore) to do anything interesting with the
language, and that's where most of the porting effort comes in.

------
6d65
Glad to see the language evolve.

It feels great, once one gets used with the borrow checker messages.

One thing that could make the language better(and was mentioned in the post)
is faster compilation.

Having programmed in Go, this may be one of its best points, just have a
watcher that recompiles the program on change(and maybe run the unittests).
Though it can be argued that not all types of programs benefit from such
workflow, it's still one of my favorite things.

~~~
pcwalton
Yes, compilation speed is one of the most important things for us. It's a lot
harder for Rust than it is for Go, because Rust has a much more sophisticated
suite of optimizations (necessary for Rust's goals) and zero-cost
abstractions. You can do a lot better if you're willing to trade runtime
performance for compilation speed, and we aren't. But I'm confident that we
can get there with incremental compilation and more codegen/typechecking
improvements.

~~~
CyberDildonics
There are plenty of situations where trading compilation speed for performance
is useful as a workflow tool. Not every build needs to be optimized to fullest
extent possible, either by Rust or by llvm.

~~~
pcwalton
Of course! But:

1\. The _language_ is designed for zero-cost abstraction, which means we have
more work to do to make it compile fast. For example, any Rust compiler must
solve subtyping constraints on lifetimes, regardless of the optimization
level.

2\. Getting an optimizing backend and a non-optimizing backend to work well is
more work than just getting a non-optimizing backend to work well.

~~~
tomp
IIRC, you usually claim that the majority of the compilation time is actually
LLVM optimizations, not Rust typechecking. If that's true, it should be
trivial to simply turn off LLVM optimization passes for DEV builds.

~~~
pcwalton
Sure, turning off LLVM optimization passes helps a lot, usually speeding up
the compile by more than 2x. Though note:

1\. There are some technical issues in LLVM that prevent Rust's -O0 from being
truly -O0 (LLVM's FastISel not supporting the invoke instruction being the
main one here).

2\. Go's compiler doesn't have much of an optimization IR at all. From what I
understand, it compiles straight from the AST to Plan 9 assembly. The
equivalent in Rust would be a backend that went straight from the AST to LLVM
MachineInstrs (like the Baseline JIT in SpiderMonkey). Such a backend would be
the ideal way to get fast whole-program compilation but would be a non-starter
for optimization, so nobody has focused on it given how much work it would be.
Incremental compilation would be a better use of people's time than
maintaining an alternate backend, because only incremental compilation gives
you algorithmic speedups (O(size of your crate) → O(size of the functions that
changed since your last rebuild)).

It still takes longer to compile Rust code than many people would like. That's
why it's being worked on.

~~~
arielby
When the MIR work is done creating a new translator would certainly be easier.

------
krat0sprakhar
> And you can do so in contexts you might not have before, dropping down from
> languages like Ruby or Python, making your first foray into systems
> programming.

I guess I'm one of those programmers who is quite alienated from systems
programming - probably due to my daily work in Python / JS. The Rust lang book
is quite good (great job @steveklabnik et al) but from my past experience I've
found it easier to stay committed to learning a new programming language when
I have a project that I can work on.

Can someone suggest a few "getting started" but useful systems programming
projects that I can use as a test bed for learning Rust?

~~~
MoOmer
Try re-implementing some of the GNU Core Utils in Rust [0]

[0]:
[http://www.gnu.org/software/coreutils/coreutils.html](http://www.gnu.org/software/coreutils/coreutils.html)

~~~
steveklabnik
Or contribute to the project that's already doing so:
[https://github.com/uutils/coreutils/](https://github.com/uutils/coreutils/)

(I myself wrote a little wc for fun a month ago, still missing some
compatibility things
[https://github.com/steveklabnik/rwc/blob/master/src/main.rs](https://github.com/steveklabnik/rwc/blob/master/src/main.rs)
)

------
gbersac
When I read it, I think two things :

1- Great job. This is both innovative and powerfull. Like the idea to test
nighties on every crate available on github. I am sure no other language does
it.

2- So much feature may be a little disappointing. Take specialization. It may
be interesting, but I don't even understand what it is. And I am not a
beginner anymore ! Don't you fear that, by adding more and more feature, rust
will become like the language it is aiming to replace (c++) : a huge mess of
feature ?

That being said, I am definitely a rust enthusiast (I bought the book
[https://www.kickstarter.com/projects/1712125778/rust-
program...](https://www.kickstarter.com/projects/1712125778/rust-programming-
concepts-book)). Carry on !

~~~
steveklabnik

      > Take specialization. It may be interesting, but I don't even
      > understand what it is. 
    

That's fair, it's hard to put a full motivation in these kinds of posts. The
RFC contains the full proposal, as well as a motivations section that
hopefully makes it more clear: [https://github.com/rust-
lang/rfcs/pull/1210](https://github.com/rust-lang/rfcs/pull/1210)

TL;DR: specialization lets you also implement a more specific version of
something that's generic. This lets you take advantage of this extra detail
for various ends, like making a particular implementation more efficient than
a general one could be.

~~~
kzrdude
It's a very detailed but also complicated proposal. It seems like it aims at
some kind of inheritance as well? I would prefer it it were simpler.

~~~
steveklabnik
It's going to end up being a key part of the future inheritance proposal, but
that's not a part of this RFC at all.

    
    
      > I would prefer if it were simpler.
    

If you have thoughts about how to simplify it, please get involved in that
thread! We don't actively try to introduce complexity, but sometimes, features
are just inherently complex. There's also the case that sometimes features are
easier to use than they are to define. I think this will be one of those kinds
of features. At its core it just means that if you have a Vec<i32> and you
also have

    
    
        impl<T> Foo for Vec<T>
    

you'll be able to define an additional

    
    
        impl Foo for Vec<i32>
    

and your Vec<i32> will use that one instead of the more general Vec<T> one.

~~~
gbersac
Now I get it. It is not that complicated after all.

------
cpeterso
How long does Crater take to compile all (2792!) crates in stock on crates.io?
It ought to be embarrassingly parallelizable. Is there a dashboard page
showing the Crater results for rust nightlies?

~~~
brson
At the moment we are using 60 r3.xlarge spot instances each running a single
build at a time, and as of a few weeks ago it took maybe two hours. It hasn't
been optimized.

There is no web dashboard yet (the website[1] - which runs Rust! - is quite
minimal), but it's coming.

[1]: [https://crater.rust-lang.org/](https://crater.rust-lang.org/)

~~~
PudgePacket
Where does the money come from to pay for these instances? Is it Mozilla?

~~~
kibwen
Yes, Mozilla currently foots the bill for Rust's infrastructure. Currently
there's no way to finance funding of Rust development directly, though we'd
happily consider accepting donations of services from companies that provide
these sort of things. :)

------
Animats
If they add 'reuse' of old compilation intermediate results, the test for
whether the source has changed should _not_ be timestamp-based. That never
works reliably, which is why "make clean; make" is so common. The source files
must be compared by some cryptographic hash.

~~~
gregwtmtno
Is that how they're doing it now? (I have experienced some trouble with cargo
detecting changes to source files on my Mac, but I can't reproduce it reliably
enough to file a bug.)

~~~
dbaupp
The compiler itself (rustc) does no form of incremental compilation: it just
takes an input crate and compiles it entirely, unconditionally.

I believe cargo (which calls out to rustc) is using timestamps at the moment.

~~~
gregwtmtno
Oh, interesting. That definitely sounds like the source of my problem. I'll
have to look in to it. Thanks.

------
BonsaiDen
For anyone interested in the talks from the recent RustCamp, the videos are
now available:
[http://confreaks.tv/events/rustcamp2015](http://confreaks.tv/events/rustcamp2015)

------
khyryk
Certainly looking forward to the borrow checker improvements as it's quite
tedious to work around the match borrowing problem.

~~~
steveklabnik
What's interesting to me about SEME regions/non-lexical borrows is that it's a
great example of a tradeoff:

Right now, the borrow checker's rules are very straightforward: references
live for the entire lexical scope that they're alive. However, the downside of
this is that sometimes you want the scope to end early, and so you have to
code around it.

With non-lexical borrows, the rules get much more complex: borrows are
determined by the control flow graph, not lexical scope. However, you no
longer need to code around those edge cases.

So the question of which is better really comes down to a question: do
programmers find reasoning about lexical scope or the CFG more intuitive? It
would appear the latter is the case, which is kind of surprising for me, but
maybe it shouldn't be.

~~~
markus2012
Can't you think of it as still being scoped - just more fine grained? Pieces
of structs can be borrow checked (what you are using) instead of the whole
struct?

~~~
pcwalton
We already do that. (See LoanPath in the compiler.) It's not a problem of
reasoning about the structure of data--it's a problem of defining a notion of
"overlapping control flow regions" that is simultaneously intuitive to the
programmer, easy to compute, sound, and satisfies the ordering constraints we
need (well-defined GLB, LUB, and partial order).

~~~
jules
Is there a real trade off between intuitive and easy to compute, versus sound
and satisfies the ordering constraints, or can you just compute the most
precise sound solution?

~~~
pcwalton
Maybe; it's unclear. The hardest part is getting the GLB/LUB/subtyping right.

------
digitalzombie
They should put having technical books on Rust as a goal.

I learn via technical books btw.

Does anybody know if there's a rust book coming out?

I mean Julia is having a book from Manning and they're not even version 1.

~~~
aturon
There's an O'Reilly book in the works: [http://www.amazon.com/Programming-
Rust-Jim-Blandy/dp/1491927...](http://www.amazon.com/Programming-Rust-Jim-
Blandy/dp/1491927283)

And The Rust Programming Language ([https://doc.rust-
lang.org/book](https://doc.rust-lang.org/book)) is on its way to paper
publication.

The newly minted Rustonomicon ([https://doc.rust-
lang.org/nightly/nomicon/](https://doc.rust-lang.org/nightly/nomicon/)) that
covers deeper aspects of Rust is hopefully destined for the same.

~~~
DominikD
All of these are great (really, not being smug) but FWIW neither TRPL nor the
Rustonomicon address my needs (Rust by example is probably the closest). It
may be related to the weird set of skills and needs I have but hey, I'll post
about my experience anyway in case someone shares my POV. ;)

My background includes OS development (Windows COM), driver development (C for
kernel mode driver and C for HW firmware development), web development
(C#/ASP.NET and JavaScript - both in browser and Node.js), and most recently
HW simulation using C++/SystemC. Mixed bag, I know. What I want to use Rust
for is desktop app development. I could go C, but that's a lot of manual
labor. I could go C# but I don't like paying cost of the runtime on desktop. I
could go C++ but I don't like getting my soul crushed. I tested viability of
Node (and Python, actually) for desktop apps but it just didn't fit my needs.

So I want to love Rust. And I kinda do. Initially I didn't like certain things
(bits of syntax mostly) but I've learned to love them. The problem is: none of
the resources tell me interesting stuff all the way through the system. I feel
like knowledge could be laid out with all the details from "this is syntax" to
"this is what happens" to "this is what you can/cannot do" to "this is why
this happens" to "this is what this means to the compiler" to "this is what
happens under the hood/in asm".

I'd also[1] love to have something that roughly maps rust to C and gives me
clear explanation of pros/cons of various approaches. It wasn't immediately
obvious to me if I can have static methods. Of whether it's important to have
self mutable (or not) as a method param. Or how to organize structures now
that I have to keep mutability in mind. I know this comes with time but I'd
love a kick of sorts. :) Best ideas tend to come from reading existing pieces
of code but rarely knows if author is worth mimicking. :S

Either way - I'm invested and I like what I'm seeing. Great work guys!

[1] or these could become one thing, dunno

~~~
Gankro
Fundamentally Rust just doesn't define things well enough to be able to answer
the "this is what it compiles to" issue.

There's some things like `Option<&T>` which we guarantee but really it's a lot
of "man, if the compiler was smart enough...". Even then, a stray annotation
can wall LLVM and kill any chances of perf (e.g. if the function is not a
candidate for cross-crate inlining).

~~~
DominikD
Oh and on an a semi related note - I get sad every time I find an interesting
looking link just to end up with 404 on the other side. This - for whatever
reason - happens far too often with Rust related resources. Trying to get to
"The Advanced Rust Programming Language Book Draft" \- no dice. Page 404s, so
does repo. Lifetime of links does matter, guys. ;(

~~~
dbaupp
That book is now [https://doc.rust-
lang.org/nightly/nomicon/](https://doc.rust-lang.org/nightly/nomicon/) . It
was published at .../adv-book/ for approximately 1 day, but then was quickly
moved.

------
drewm1980
Are compiler features to support writing something like libeigen still on the
roadmap? rust is IMHO a bit of a non-starter for many engineering fields until
it has a really good story for array math.

~~~
steveklabnik
That's more of language typesystem features, and they still are, but we're
focusing on work that will make said work easier in the future, rather than
going straight to it.

~~~
drewm1980
Ok, thanks!

------
PudgePacket
"We plan to extend the compiler to permit deeper integration with IDEs and
other tools; the plan is to focus initially on two IDEs, and then grow from
there."

Any ideas which IDEs will be chosen?

~~~
steveklabnik
Visual Studio and another yet-to-be-determined one.

------
jhasse
Sounds wonderful! I especially can't wait for incremental compilation. I can't
understand how others do any work without it.

~~~
steveklabnik
Since crates are the compilation boundary, and you can make projects out of
multiple crates, larger Rust projects tend to be split up, even internally.

Take Servo, for instance:
[https://github.com/servo/servo/tree/master/components](https://github.com/servo/servo/tree/master/components)
or rustc itself: [https://github.com/rust-
lang/rust/tree/master/src](https://github.com/rust-lang/rust/tree/master/src)

Each of these subdirectories (basically, a few aren't) is a crate, so you'll
only be recompiling stuff in the subdirectory you're editing. Incremental
compilation will still help with projects like this, of course.

~~~
saosebastiao
Is it possible for rust to optimize across crate boundaries?

~~~
steveklabnik
With LTO, yes. I always forget if #[inline] does or not.

~~~
chrismorgan
#[inline] is _all about_ cross-crate work; inside a crate, items not marked
#[inline] may still be inlined by the optimiser, but it doesn’t do cross-crate
inlining without #[inline] or LTO.

~~~
ben0x539
Are generics not inlined when appropriate even without #[inline] or LTO?

~~~
kibwen
You don't need the #[inline] attribute when generics are involved, because
Rust already has to cross-crate-export function metadata when generics are
involved because otherwise it would be impossible to monomorphize. At that
point, LLVM will inline the monomorphized functions as it deems fit.

------
nnethercote
> Rust’s greatest potential is to unlock a new generation of systems
> programmers. And that’s not just because of the language; it’s just as much
> because of a community culture that says “Don’t know the difference between
> the stack and the heap? Don’t worry, Rust is a great way to learn about it,
> and I’d love to show you how.”

Wonderful stuff.

------
grayrest
Is there an RFC or thread covering the IDE integration plans?

~~~
aturon
Not yet, but Nick Cameron (@nrc) has been holding talks with many IDE makers
and plans to launch a "Rust IDE initiative" very soon.

~~~
SneakerXZ
It would be nice to have something to Atom. Like
[http://nuclide.io/](http://nuclide.io/) with built-in building pipeline,
syntax highlighting, smart code completion, and error checking and some basic
support for refactoring.

I would prefer that over plugin to Eclipse or Intellij IDEA.

------
Fede_V
I am very excited to see the focus on tooling. Rust is a kick ass language,
but imagine how awesome it would be to have an IDE to help you with lifetimes,
inline documentation, etc...

C#'s best feature is its integration with visual studio. Rust would greatly
benefit from something similar.

------
joliv
Aaron Turon and Niko Matsakis gave a talk on this for their Rust Camp keynote,
you can see slides on it here if you prefer that format:

[http://rustcamp.com/schedule.html](http://rustcamp.com/schedule.html)

------
coldcode
It will be interesting to see Rust and Swift evolve as Swift moves to the
server side (at least on Linux). Both are modern languages although each has
its own target users.

------
jebblue
There are 5 hits on dice.com for "rust".

~~~
steveklabnik
Yes, there are few dedicated Rust jobs yet. Most organizations that are using
Rust in production are using programmers they've already hired rather than
hiring new ones specifically for Rust.

It's a newly stable language, these things take time.

