fireflowers

The Rust Programming Language
in the words of its practitioners.

Rust is a systems programming language that is perhaps most notable for being memory safe without garbage collection. It was designed to solve problems observed maintaining the millions of lines of C++ in the Firefox web browser. It is fast, reliable, and runs on most anything, and its enthusiasts are exceptionally enthusiastic about its potential.

On December 29, 2016, Steve Klabnik, author of The Rust Book and member of the Rust core team, blogged, "Rust is more than safety", saying that memory safety alone is not convincing for some prospective Rust users. This catalyzed a blogsplosion the likes of which Rustaceans had never seen (and Rustaceans love blogging), where Rust's creators and users offered their opinions about what makes Rust so exciting.

This is a summary of that.

"Rust is more than safety"  •  Steve Klabnik
Comment threads: /r/rust hn

In this initial post, Steve claims that "Rust is most well-known for its features around writing low-level code in a safer way than its predecessors. But it’s also a lot more than that." He suggests that Rust brings established modern programming language theory to the domain of systems programming, emphasizing a slogan from Rust's creator, Graydon Hoare:

Technology from the past
come to save the future from itself

The rediscovery and application of old, reliable, and sometimes forgotten technology is one of the themes the name "Rust" evokes. Rust applies some established techniques from academia to industry. Steve doesn't elaborate, but two obvious examples are that Rust includes algebraic data types, common in the ML family of languages, and in Rust known as "enums"; and traits, which enable polymorphism similar to Haskell's type classes, but fairly unlike C++ classes and templates.

How Rust innovates the greatest is by statically tracking ownership and lifetimes of all variables and their references. The ownership system enables Rust to automatically deallocate and run destructors on all values immediately when they go out of scope, and prevents values from being accessed after they are destroyed. It is what makes Rust memory safe and thread safe, and why it doesn't need a GC to accomplish that.

And that's cool. But, as Steve goes on to say, "your marketing should be focused on what problems your product solves for the consumer". Being memory safe (i.e. "not crashing") is nice, but many programmers of languages with garbage collectors enjoy that comfort today, and some C and C++ programmers are dismissive of the value of memory safety, possibly believing they have a handle on the matters of memory management and concurrency.

Selected commentary

The borrow checker is amazing! I hated it at first, but ownership and lifetimes don't just bring sense to multithreaded and concurrent programming, they also make your own data designs so much cleaner!

Rust, through ownership, effectively enforces the higher-level single responsibility principle that sometimes is a struggle to be consistent about in other languages. That alone is amazing.

But for me, what really gets me is how expressive it can be and yet it seems like we lose nothing in terms of security, reliability, predictability and efficiency. That's just a dream.

Jacksonmills

Rust makes it easier to write correct and readable code, and getting both at the same time is not a coincidence.

The very mechanisms of ownership/borrowing (a tight control over lifetime, aliasing and mutability) enforce a certain simplicity in the data-flow of the resulting software that you could get in other programming languages, but generally do not because the language was more lenient and you got away with a more convoluted flow.

Have you ever had to debug a ConcurrentModificationException in Java? This happens when you modify a container being iterated over. When you have a chain of callbacks/observers, it's incredibly easy to accidentally have a circular reference leading to this exception. In Rust, to get to this situation you have to use RefCell or equivalent, and it should make you pause.

Matthieum

Another thing I love with Rust is its balance between ease of use and fastness. Not only there are lots of high level features that are really cool in the language, but cargo/crates.io makes publishing a package very easy; while dynamically typed languages might seem easier sometimes I feel that if you are not rigorous (and I'm not, see the beginning of this comment :p) it's difficult to buy medium-scaled projects in them; and at the same time Rust is fast, and even when performances aren't critical, well, it's always good, plus in my experience some thing that isn't performance-critical can quickly become it (e.g. it doesn't matter if it takes 10ms or 100 when you run something as a command line, but then you're like "hey I could turn that into a webservice too" and it starts to matter).

There are a few languages I am quite familiar with, and some that I really like, but Rust is the one I found the most empowering. The problem with "safety" is that in programming when I read that word I tend to think that it's something for low-level stuff or things that can have security issues and I don't usually need that, but in the end I think that safety also leads to confidence: my code might not be best written, but with the compiler I can be confident that it's relatively correct (obviously it can't catch everything but well), which isn't the case with most other languages.

Lise_henry
  1. Fast program execution. Sometimes you just want the speed that a scripting language cannot provide. Although I have to admit that many times Python is fast enough. I also pick D sometimes to write fast "scripts".
  2. Reliability. Rust is a language that puts an emphasis on correct and reliable programs. The compiler does a great job at pointing me at pieces of code that I should think about again. It is similar to Haskell in that "if it compiles, it is likely correct". You pay upfront for long "talk to the compiler" sessions, but from experience I'd say that it pays off.
  3. A language that is a joy to use. There are some really great languages that I love to use. They include Clojure, Lua, Python and Rust. The first two languages are mostly the products from single inventors with good taste plus a couple of contributors. The last two are the product of their respective communities. The Rust community tries to bring together the best ideas and lessons from different programming languages and has a democratic development process that tries to create a language and an ecosystem that is nice to use and plays well together with Rust's goals.
  4. A new language with stable releases. I like to try new programming languages from time to time. It is cool that you can pick between stable, beta and nightly, depending on your stability needs. Furthermore, you can count on Rust being around for longer because Mozilla is supporting the language.
xling

It's really difficult for me to talk about rust without talking about safety. I write C++ for a living on a relatively large stack. It sucks to hunt down a sporadic double delete. So much.

One thing I don't think gets touched on enough is how much easier refactoring is because of the borrow checker. I think it's easier to see the lifetime of objects in rust, so it's easier to find blocks of code that can be extracted into a function or structure. It is very nice to be able to bang out some code (that works correctly, thank you borrow checker), and refactor it later on without too much of a hassle.

Vrj

Concrete practical points that might interest a C programmer/engineer: (Those are obviously obvious to /r/rust regulars)

  • The language is relatively small. -- That's rarely mentioned.
  • No more wrapping std functions for safety and error-checking. Or banning some of the functions that are deemed dangerous. Or using a complete safe replacement library because you don't trust yourself or others.
  • Abstractions are opt-in. Safe guards are opt-out.
  • The language is not OOP-centric. You wouldn't be forced into a paradigm that never made sense to you. Or forced to use needless abstractions you never liked.
  • You can use native performant libraries freely. You will never have to check if a library is shipped by all major distributions. You don't have to worry about the versions shipped. -- More maturity and completeness in the crate ecosystem is essential here.
  • Static checking is (mostly) built-in. You don't have to depend on imperfect proprietary tools/services like Coverity anymore.
  • A build tool is included. And the build process is unified and streamlined. No more autotools/CMake/(g|n|b|p|f|s|d)make/etc shenanigans.

This relates better, IMHO, to the pain points C users face, than general talk about safety design. Once a user dips their toes in Rust. They will start to grasp the bigger picture.

Acc_test

Rust, to me, has a number of things going for it beyond safety:

  • If it compiles, it works: Rust and Haskell are the only languages I've seen where this has regularly been the case.
  • Embedding: I think this is a killer feature. If you want to make a native extension for python, ruby, nodejs or erlang to get some additional performance or to integrate with native libraries rust is a great way to do it. The absence of a GC in rust lets it cooperate with other language runtimes without issues. This is an area where the only other competition has been C or C++.
  • Dependency management: Rust doesn't just provide a better dependency management situation vs C and C++ but other languages too. I like working with cargo more than pip or npm and because it is the official tool it seems rust will be able to avoid the proliferation and fragmentation of tools that other languages have experienced.

Chowmeined

If C is like playing with knives and C++ is juggling chainsaws, Rust is like parkour suspended from strings and wearing protective gear. It'll look ridiculous at times, but you'll be able to do all sorts of cool moves that would otherwise be damn scary or outright impossible. You'll have so much fun you'll start trying to do it in other languages, too. And many of us never look back.

Also you get new improved gear every six weeks, and between this and your newly built muscles, you start feeling like a super hero. This feeling is amplified by the community, which simultaneously does awesome feats and is really humble and open about it (you're by now accustomed to people being good at concurrency, and get slightly annoyed that your snake-charming friends insist on doing everything one step at a time).

You also met some folks you wouldn't have expected here, from a number of dynamic languages, braving the learning curve to descend into low-level programming, usually singing Rust's praises with unreal sounding benchmark comparisons.

You start looking with pity at your knive- and chainsaw-wielding friends. You see both their bruises and denial about said bruises. You'd want to offer them some of that awesome protective gear (by now you no longer feel the strings, because they seldom get taut), but you know the answer already. Poor folks.

Llogiq

A big non-safety selling point of Rust for me is a systems language with the tooling and ecosystem of a modern dynamic language. Dependency management and composition is a necessary part of complex programs, but a tedious, painful timesink in almost all systems languages. While CMake and similar tools improved the situation for C++, it's still an enormous pain and a barrier to sharing and reusing code. You are often forced to re-invent the wheel -- complete with your own bugs and maintenance obligation -- simply because getting a dependency to be built and detected cross-platform may be an even larger cost.

Cargo is a wonder. It's more limited in scope than something like CMake, but for the vast majority of use cases that are just pulling in a library or binding from the same language, it's spectacular.

aschampion

Apart from big differences between Java and Rust like memory management (not just GC vs. lifetimes but also stack allocation), approach to threading, and Cargo vs. Maven, Rust is so much nicer in the seemingly little things like:

  • UTF-8 everywhere instead of UTF-16 everywhere.
  • Unsigned integers.
  • Bytes from I/O being unsigned by convention.
  • Ability to bake plain old data into the data segment of the executable with genuinely no run-time initialization.

hsivonen

I haven't developed this thesis fully, but I've been thinking that Rust's model is a better version of functional programming, and we lack a good term for it (since it's obviously not a pure functional language). The point of functional programming is to avoid shared mutable state by eliminating all side effects and using a rich type system that's hopefully easy for the programmer to use. Rust avoids unsafe shared mutable state, without requiring the avoidance of all side effects, and by using an even richer static-analysis system that tracks exactly what side effects are safe.

Of course, there are a lot of useful things a pure functional programming language gets you, like Haskell's implicit IO scheduling and threading, that Rust doesn't. But for many use cases where functional programming languages are great, they're great for specific reasons that Rust is also great at.

geofft

One of my favorite things about Rust is one of the practical applications of the safety. Specifically, it's that I can write multithreaded code without fear because the compiler won't let me get it wrong. It's far far far too easy to screw up multithreaded code if you're using any kind of shared data, and Rust is the only language I know of that truly makes it safe without compromising on performance.

As a trivial example, some time ago I fixed a subtle threading bug in fish-shell. The code used RAII and lock guards, which is good, but in this particular case the lock guard was created using the wrong lock. So it was locking, it just wasn't locking the correct lock, meaning the data it was mutating was subject to a data race. As I fixed that, I found myself wishing the program had been written in Rust, because that sort of bug simply won't happen in Rust.

eridius

As someone who's been in the system programming space for a while and played with Rust for ~1.5 years here's my highlights.

  1. I haven't written any multithreading code yet but I love the borrow-checker since it does a fantastic job of dealing with mutable state. I find I get better architected programs with single-ownership long before I start writing Rust and I love to see the compiler enforce it.
  2. ADTs. Simply the best way to represent State + Data bar none. Combine with pattern matching and it's just sublime.
  3. Iterators. Never seen a language do them so well with so little overhead. The focus on zero-cost abstractions really shines here.
  4. Cross platform support. This is a huge one. Having dealt with MSCV/GCC/LLVM/custom compiler toolchains I can't stress to wonderful it is to have a consistent compiler that can build other targets on a different host.
  5. Cargo, other people have covered it, enough said.
  6. The community. Truly one of the better ones out there who not only want to help but also provides releases like clockwork with clear semantics on stability and APIs.

vvanders

"Rust is mostly safety"  •  Graydon Hoare
Comment threads: /r/rust hn

So in response to Steve's post there were a number of opinions expressed about Rust, and about the importance of "safety". In this response, Graydon Hoare, Rust's erstwhile creator, reminds us that "safety in the systems space is Rust's raison d'être. Especially safe concurrency."

Graydon has strong words for C++ programmers who deny the importance of memory safety:

When someone says they "don't have safety problems" in C++, I am astonished: a statement that must be made in ignorance, if not outright negligence. The fact of the matter is that the further down the software stack one goes, the worse the safety situation gets. Our engineering discipline has this dirty secret, but it is not so secret anymore: every day the world stumbles forward on creaky, malfunctioning, vulnerable, error-prone systems software and every day the toll in human misery increases. Billions of dollars, countless lives lost. Can one really say "I don't have safety problems" in systems programming?"

He asserts that "Rust's success in raising the bar for safe, concurrent systems programming — in ways that the niche finds usable, performant and compatible — cannot (imo) be overstated. That is its purpose, and that has been its great success."

Selected commentary

I think "fearless concurrency" is a better pitch for Rust than "memory safety." The former is "Hey, you know that thing that's really hard for you? Rust makes it easy." The latter is, as Dave says, "eat your vegetables."

Steveklabnik1

I would argue that if the Rust project would have just one mission statement, it wouldn't be "create a safe systems programming language". It would be "move towards a world where safe systems programming is the norm".

What's the difference? Both of the statements have the premise that Rust is – and ought to be – a safe systems programming language. However, the latter captures not only the REAL goal, but also the nuances and tensions: while safety is indispensable, we must do something else too, for the programming society to accept the safe tools we are trying to promote. That means ergonomics, that means performance, that means ease of use, that means wide availability – and that might also mean advocation of visions of a better world, which is what this blog post of Graydon's does.

GolDDranks

Talking about the safety is fundamentally not so attractive to many of our potential users -- they're either C/C++ people who have evolved coping strategies to deal with all the pitfalls, or they're dynamic language people who get the safety, too, just at a performance cost.

So, I really like the "fearless" part. For me personally, the "concurrency" part isn't as interesting; really, how much of the code you write on a day-to-day basis needs to reckon with concurrency issues? I would think that's a tiny percentage for most developers. One could argue that this is exactly because concurrency is so bothersome/failure-prone in most existing advantages, but then we're back to the "eat your vegetables" argument.

So maybe it would be better to talk about "fearless performance", or "fearless zero-cost abstractions", or "low-level control without the hazards".

Dochtman

Rust gives you fearlessness in all the things, but it does mean learning new style and discovering new solutions to old problems. To fully understand 'Send' vs. 'Sync', for example, means really groking the Rust type system. Once you get the type system, then fully utilizing it with the expressive generics becomes unlocked, and then at that point you've transcended from Rust dabbler to fully fearless Rust user.

Once this world of development is unlocked to you it is mind-blowing, but it is a journey to get there, and not everyone will have the heart to make it. It comes in stages, is wonderfully rewarding, will make you a better programmer in you other favorite languages, but I think we should be careful with statements like 'Rust makes it easy'.

It does make hard things easy, but only after you've fully embraced Rust. This feels more accurate: "Hey, you know that thing that's really hard for you? Rust makes it fun."

bluejekyll

I'm a lowly ancient Java programmer and I think Rust is far far more than safety.

In my opinion Rust is about doing things right. It may have been about safety at first but I think it is more than that given the work of the community.

Yes I know there is the right tool for the right job and is impossible to fill all use cases but IMO Rust is striving for iPhone like usage.

I have never seen a more disciplined and balanced community approach to creating PL. Everything seems to be carefully thought out and iterated on. There is a lot to be said to this (although ironically I suppose one could call that safe)!

PL is more than the language. It is works, community and mindshare.

If Rust was so concerned with safety I don't think much work would be done on making it so consumable for all with continuous improvements of compiler error messages, easier syntax and improved documentation.

Rust is one of the first languages in a long time that makes you think different.

If it is just safety... safety is one overloaded word.

agentgt

"Safety is Rust's fireflower"  •  Dave Herman
Comment threads: /r/rust

So this is where we come to fireflowers. Dave Herman is a founder of Mozilla Research, a member of TC39, the JavaScript standards body, one of Rust's greatest advocates, and he likes vivid metaphors.

The fireflower in the title is a metaphor drawn from Super Mario Bros. In the game, when Mario eats a Fire Flower, he becomes Fire Mario, a fireball-throwing badass. In the metaphor, which Dave attributes to Samuel Hulick, one wants your users (Mario) to feel like Fire Mario when they use your product (Fire Flowers).

And Dave's point is that safety is the Fire Flower that enables Rust developers to be Fire Mario.

He then goes on to talk about the superpowers the Rust Fire Flower gives to Rust Fire Marios:

So what's badass about programming in Rust? I think it's being a systems programmer. There's nothing a systems programmer can't do: write an OS from scratch; drive micro-controllers; outcompete the fastest software in a crowded category; it's all within reach.

But for most programmers, the prospect of writing C or C++ code — and certainly the thought of actually shipping it — is so terrifying we don't usually even waste much time considering it.

This is why I believe hack without fear resonates: safety clears one of the biggest obstacles preventing people from seeing themselves as systems programmers.

Selected commentary

One very important thing that isnt emphasized enough is that Rust makes systems programming accessible.

With C and C++ the barrier of entry is harder.

This is huge. This means more devs can become systems programmers. More people writing systems software. I think this is why rust has more success recruiting new devs from higher level languages and newbies than C/C++ devs.

In that sense, the fire flower makes systems programming accessible. And fire mario are devs who can write system programs.

Kosinix

"Fire Mario, not Fire Flowers"  •  Steve Klabnik
Comment threads: /r/rust

Steve is into the "fearless" theme and suggests that being fearless makes you Fire Mario, whereas safety remains just the Fire Flower: "I’m not saying that we get rid of fire flowers. I’m saying that we focus on 'Rust makes you Fire Mario', not 'Rust is made of fire flowers', when talking to people about Rust." (But "Rust is made of fire flowers" sounds amazing, right? I don't think that can be disputed.)

He drives the point home:

I think one of Rust’s greatest potentials ... is bringing a ton of new people into systems programming. But my point is this: “memory safety without garbage collection” doesn’t speak to that at all. That is, memory safety without garbage collection is the mechanism of how that’s accomplished, but it’s not the accomplishment itself. It’s the Fire Flower, not Fire Mario.

I’d like to make sure we’re talking about being Fire Mario, rather than being Fire Flower enthusiasts.

Selected commentary

Instead of going back and forth with blog posts I think the whole thing should just be settled next month at the Royal Rumble.

Malicious_turtle

Epilogue

Well, that wasn't the end of it, just the end of what I've summarized. Here are some others' thoughts on the subject:

At that point Sontikka observed that "Rust is mostly blog posts", kibwen declared that "Rust is literally Haskell" , and /r/rust collapsed into memery for a few days in celebration .

As to what we should learn from this,

fireflowers