
Rust is more than safety - anp
http://words.steveklabnik.com/rust-is-more-than-safety
======
Xorlev
For me, Rust is a return to performance without compromising on high-level
abstractions (e.g. iterator methods). Rust is very expressive, but at the same
time safe and has your back on performance and keeps you safe. Honestly, I
feel safer writing in Rust than I do Java. Even Java has its footguns,
especially with mutable state being shared across threads. I can't really
comment on C++ as I have never written it professionally.

Rust not being a garbage collected language leaves it free to focus on more
important problems as well. Not knocking the difficulty of implementing the
borrow checker, but once you have GC in a language you spend forever tuning to
fit your users' workloads. Unless you're Go, then you optimize for latency at
the cost of CPU, but that seems like a very acceptable tradeoff to make given
how Go is most commonly used.

I've never seen a single language with so much promise for both systems
programming and service/application development.

Edit: Forgot to mention, every time I tried to get into C++, I was always
reminded how good I have dependency management in Java. Rust is even better
than Java in that realm; Cargo is an amazing piece of software. In that
context I like Rust for the same reason I like Go: opinionated tooling. I
might not always agree with the decisions, but at least it's opinionated and
easy to work with.

~~~
idobai
If you're into safety than you should probably go with a functional
programming language with low-cost abstractions. Rust isn't an expressive
language, its only benefit compared to other general purpose languages is its
memory management.

~~~
geofft
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.

~~~
Manishearth
A common point I've seen is that "Functional programming sees the aliasing vs
mutability issue and declares that the solution is to avoid mutability
altogether. Rust goes in a different direction, saying that only aliasing XOR
mutability is allowed".

It's solving the same problems, and the solution ends up having many
similarities with functional programming.

~~~
jholman
When people keep writing "aliasing XOR mutability", don't they actually mean
"aliasing NAND mutability"? And if yes, is there a reason to use XOR here? And
if no, isn't it the case that if it's worth communicating, it's worth
communicating clearly?

------
aschampion
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.

Related to this, having an opinionated lint built into the tooling creates a
common, readable dialect for the ecosystem. This is especially important for
verbose syntax languages like Rust or C++. There are C++ libraries I can't
understand simply because special snowflake formatting combined with complex
template syntax renders it illegible.

~~~
zzzcpan
Last time I checked cargo was still not handling external dependencies and the
packages were simply wrapping system-wide dependencies, that you have to
manage yourself. Same problem as with all CPAN-derived package managers.

~~~
the_mitsuhiko
It is intentionally not handling external dependencies. That's not what it's
for. Many libraries and wrappers will compile the library if missing on the
system (eg: rust-curl as a practical example will compile curl and statically
link it if needed).

~~~
zzzcpan
CPAN did it exactly like that, many packages also bundled C libraries, etc.
It's a very fragile mess and a mistake package managers refused to learn from
CPAN. It is especially pronounced once you have a CI/CD system, forces you to
pretty much abandon such package managers and only use them to
explore/discover new packages.

~~~
kibwen
_> forces you to pretty much abandon such package managers and only use them
to explore/discover new packages_

Given the unbelievable popularity of Rubygems.org, PyPI, and NPM, I think this
is an unfounded assertion. Furthermore, Rust programmers aren't afraid to
rewrite libs in Rust when a widespread external dependency becomes annoying,
e.g. with FreeType:
[https://www.reddit.com/r/rust/comments/44btaz/introducing_ru...](https://www.reddit.com/r/rust/comments/44btaz/introducing_rusttype_a_pure_rust_alternative_to/)

------
eridius
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.

~~~
dispose13432
That's one thing I _hate_ about Go, is how easy it is to shoot yourself in the
foot with it.

Really, it has a decent way to manage inter-thread communication - channels.
But the language still permits me to read/write a "non const" global variable
from a goroutine.

This is horrible, especially when refactoring.

Each goroutine should have it's own scope (unless explicitly defined).

~~~
atombender
More than once I've also had to kick myself for making the rookie mistake of
closing over a loop variable. So something like:

    
    
        for _, v := range values {
          go func() {
            // Do stuff with v
          }
        }
    

Instead of:

    
    
        for _, v := range values {
          go (func(v string) {
            // Do stuff with value
          })(v)
        }
    

It's rare enough, and subtle enough, that every instance tends to result in
5-10 minutes of puzzled debugging with stdout printing statements until I
realize what's going on. What does Rust do here?

I like to say that Go's strictness is unevenly distributed. Unused imports are
illegal, but Go is perfectly happy to let you shadow variables, have closure
use loop variables, or reassign the built-in values ("nil", "true", etc.).
It's like a parent who locks the scissors away in a drawer but doesn't mind
leaving drain cleaner on the kitchen table.

~~~
electrum
Fortunately, that mistake isn't possible in Java with lambda expressions or
anonymous classes. It is a compile error if any captured variables are not
"effectively final".

Prior to Java 8, which introduced lambdas, variables used with anonymous
classes were required to be final. That restriction is now relaxed as the
compiler can infer it.

Interestingly, the for-each loop variable is effectively final, unless you
explicitly modify it, so this code is legal (and correct):

    
    
      for (String v : values) {
          executor.execute(() -> System.out.println(v));
      }

~~~
dkersten
I like that in C++11, you specify what should be captured and how it should be
captured (by value or by reference).

~~~
masklinn
Rust is the same, though it's less flexible[0]: it doesn't have capture lists,
only [&] and [=], and they're very slightly different:

* the default is similar to [&] but will infer the capture mode and use the "simplest" possible one (reference, mutable reference or value) depending on use on a per-value basis.

* `move` closures are similar to [=] but will use Rust ownership semantics, so they will copy Copy values and move non-Copy values, it can capture external references (mutable or not) by value so if you needed to explicitly tweak your capture that's the one you'd use.

[0] OTOH it's more readable

~~~
steveklabnik
I'm not sure that "less flexible" is accurate; we can accomplish the same
things, but through different means.

~~~
masklinn
It might have been unclear, but I meant the closure syntax/capture itself is
less flexible. You can get the same result e.g. using a move closure and
declaring references outside the closure then capturing _that_ by value, but
I'm sure you could also do that in C++.

~~~
steveklabnik
Ah, yes. Cool :)

------
vvanders
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.

~~~
Manishearth
FWIW that the borrow checker has nothing to do with multithreading, all the
guarantees enforced are important in single threaded contexts.

[http://manishearth.github.io/blog/2015/05/17/the-problem-
wit...](http://manishearth.github.io/blog/2015/05/17/the-problem-with-shared-
mutability/)

It's a prerequisite for safe scoped multithreading, but that's about it.

~~~
vvanders
Fair enough, it's a common enough refrain that I wanted to point out
specifically that there's lots of benefits to it outside of memory safety.

------
sidlls
The biggest flaw in Rust's marketing, as far as I can tell, isn't noting that
it's safer than C or C++, or that it's a systems programming language, it's
the simultaneous (implicit and explicit) confrontational bashing on languages
that aren't Rust, but especially C and C++, and the egregious ego-inflating
comparisons (x-in-Rust is y-times-as-fast-as-x-in-C-or-C++).

I've only written a few relatively small ("toy") applications to completion in
Rust. I have one application I'm working on in Rust at work, which is in an
advanced stage of development and that will replace a significant part of our
production-deployed current implementation (in python). I also have one
application I'm working on in my spare time that is not a toy (although it is
for entertainment purposes). My view is that for a good number of tasks Rust
is nicer to use than C++, and probably I'd reach for Rust before C++ in
instances where I'd normally choose C++. It would depend heavily on the
context when comparing Rust vs. C. The safety argument simply doesn't register
most of the time.

No, this isn't because "I don't have problems writing safe C or C++ code,"
(although I certainly expect the above comment to be misinterpreted
uncharitably in this way) this is because the kinds of safety guarantees Rust
provides simply don't register on the list of reasons to explicitly choose it
(over C or C++) in a large number of contexts. Even in contexts where it does
matter, the current state of affairs is that those terrible languages, C and
C++, run the world well enough. There are some pretty good examples of
terrible safety flaws that may have been avoided with Rust's guarantees. These
aren't universally applicable to all problems to be solved in programming.

My advice, for all it's worth, is to stop hyper-focusing on safety and
definitely stop the oblique insults to C, C++ (and other languages--some
notable GC'd ones come to mind, from recent posts and comments I've seen
around here). Rust has so much more to offer than an implementation detail
(which is what "safety" is).

~~~
ovao
Interesting comment. I'm not sure Rust's safety guarantees are what many would
consider _merely_ an "implementation detail". Aren't the merits and caveats in
any programming language (not with regard to its overall ecosystem), just
implementation details? Or is my line of thinking not correct about that?

I'd agree with you on this point if a language really marketed its relatively
simple safety facilities — like, say, C++11's std::shared_ptr — but relatively
high-level (or perhaps "mid-level") guarantees provided by the standard or by
the implementation strike me as features of real substance. Something
substantial enough that I would take it into account in choosing a language,
among many other things, and I think Rust's are relevant to a large number of
systems.

From what I can tell Rust is being marketed well enough to create a lot of
enthusiasm. I don't know if that's necessarily an indication that it's being
marketed _properly_ (by whatever definition of "properly" makes sense).

~~~
jolux
The safety features of Rust are core to the design of the language, that's
what makes it so effective. It essentially takes part of what makes the design
of pure functional programming so safe and makes it highly performant and
pragmatic for a systems programming context. An implementation detail would be
like the intricacies of better code generation, which is not at all key to
Rust.

Granted, it's "C fast," but the whole point of the safety features is that
they are intrinsic and pervasive to how the language functions so that the
programmer is not allowed to make certain kinds of mistakes that C and C++ are
totally fine with and will generate crashing code for. It's not just about
making unsafe programming practices safe through better compiler practices,
it's about stopping the unsafe programs before they reach the compilation
step.

~~~
akiselev
_> It's not just about making unsafe programming practices safe through better
compiler practices, it's about stopping the unsafe programs before they reach
the compilation step._

I would like to add to the end of that: "...unless you explicitly tell the
compiler to do it." I can't think of anything that you can do in C that you
can't do in Rust unsafe blocks, you just have to tell the compiler explicitly.

~~~
jolux
Yes, the unsafe parts are always explicit so you never forget about the
gravity of working with unsafe code.

------
Animats
A sales pitch asking others to help you with your sales pitch. That's a good
marketing concept. It's similar to "ordinary people say why X is great" ads.

Beyond the safety issue, I'm still not clear on how to think about Rust. It's
mostly an imperative language at the language level, but it has so much
functional programming stuff in templates that it looks like a functional one.
It's often hard to visualize what all that stuff is doing. Did that ".collect"
generate a big intermediate array? How can you tell without looking at the
generated code? What kind of development environment would help?

Rust uses closures very heavily for routine functions. That's a big change in
thinking for C programmers.

The module system seems clunky. There are modules, and crates, and TOML files,
and module statements, and required directory structure. Adding a module seems
to require editing about three files. The management of imported names seems
unnecessarily obtuse, too. Having both "extern" and "use" seems overkill. Most
languages get by with a single "import" statement.

I see all this as an acceptable price to pay for safety, but it's rough on
many programmers.

~~~
ucarion
Though I knew how to use them, I didn't understand how Rust closures could
work until I read these articles:

[https://doc.rust-lang.org/book/closures.html](https://doc.rust-
lang.org/book/closures.html)

[https://doc.rust-lang.org/book/trait-objects.html](https://doc.rust-
lang.org/book/trait-objects.html)

Basically, a closure is just an anonymous trait, and traits are implemented
with vtables. This reminds me of how you can think of Java's lambdas as
anonymous classes (though they're not implemented that way).

~~~
tatterdemalion
Close. :-) Closures are anonymous _types_ which implement one of the Fn traits
(which are not anonymous). Traits are _usually not_ implemented with vtables;
they are usually monomorphized and statically dispatched (this includes most
higher order functions). If you need dynamic dispatch, they can be cast into
"trait objects" with vtables. This is a pretty big deal - static dispatch is
why functionalish abstractions like map and filter can compile to a very tight
loop.

~~~
Animats
And you wonder why C programmers have trouble with Rust.

~~~
akiselev
No one in their right mind is wondering that. Going from "go ahead, do
whatever you want" memory management to Rust's ownerhsip system or object
oriented programming to trait based programming isn't something anyone excepts
to happen without some perseverance.

~~~
Animats
"Expects", I think.

Ask who really needs Rust. People who write code that has to work and causes
real trouble when it doesn't. That includes embedded system programmers.
They're typically into C and can use an oscilloscope. They seldom know C++ and
have never heard of Haskell. But they can lay out a circuit board and get it
to work.

Rust needs to be accessible to those people.

------
xling
It solves the following problems for me:

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.

------
Philipp__
Rust left big impression on me mostly because I was amazed that there exists
functional language in Systems programming world! There, C is the absolute
king, even Cpp doesn't cut it sometimes (when we are coming close to embedded
world). Writing in Rust really feels like "programming" and not "systems
programming", because of the way you approach the problems that are bound
relatively close to metal. And community is amazing. So I just hope I gain
more knowledge and time, so I can start playing with it properly.

Disclaimer: I haven't programmed a lot in Rust, because I am busy learning
other thing atm (student heh), but I am following it for 2 years now, and
reading a lot about it, occasionally I write some small programs.

~~~
nickpsecurity
If you like that concept, then check out this functional language in system
programming that didn't require a LISP machine:

[https://en.wikipedia.org/wiki/PreScheme](https://en.wikipedia.org/wiki/PreScheme)

The House and MirageOS operating systems also put Haskell and Ocaml to work
for this respectively. House even did drivers in Haskell with a modified
version of hop. Here's their site:

[http://programatica.cs.pdx.edu/House/](http://programatica.cs.pdx.edu/House/)

------
nickpsecurity
"'[Rust is] Technology from the past come to save the future from itself'

He goes on to elaborate a bit:

    
    
        'Many older languages [are] better than new ones. We keep forgetting already-learned lessons.'"
    

Loving how this Graydon person thinks already. Same stuff pjmlp and I are
always saying. Except he built something that took off massively with
Mozilla's help. Extra credit there to both. Now, what might happen if this
kind of thinking was applied all over the stack? I need 100 volunteers.

Start with VMS-style versioning for critical files (esp system or
application), clustering, distributed locking, and app API to leverage all
that easily. Put that in the good Linux or BSD disros. Maybe they'll stop
eating my files or the services popular on HN will crash less. If they get
that done, we're adding Microsoft's approach to drivers that work if they
reject that of MINIX 3 or Genode. We can also use TLA+, Coq, SPARK, and/or
Rust since those were things in the past that worked too on the kinds of
problems this effort will introduce.

Systems and services should get really reliable after this. I won't even care
about Linux kernel crashes as it will be a VM that goes down with my critical
work checkpointed into another on same machine on a microkernel. A little
driver reset happens then new one gets focus while old VM resets in background
then joins cluster. For some extra money, this happens with physical
separation in a desktop with two motherboards, one on each side, similar to
old SGI Octanes. :)

~~~
qwertyuiop924
>Loving how this Graydon person thinks already. Same stuff pjmlp and I are
always saying.

Rust was bootstrapped by a compiler written in OCaML.

Like you and pjmlp, Graydon is a massive fan of fanatically strong typing, and
most of that stuff was actually in many older languages that lost because C
was an optimal solution at the time.

However, at scale, C is no longer an optimal solution. Thus Rust can start
eating C/C++'s lunch, and people will stop using C for what it does badly, and
using it for what it does well (namely, writing small programs that do one
thing and do it well, doing embedded work, kernels, and other bit hacking, and
bootstrapping better languages).

~~~
nickpsecurity
"Rust was bootstrapped by a compiler written in OCaML."

Another wise choice. I gave them credit for that, too, when they told me.

"because C was an optimal solution at the time."

Whoa, we've talked about this before. It's closer to an optimal solution if
you're squeezing max performance out of old hardware with a higher-than-
assembly language. It wasn't optimal on ease of compilation, safety, large
programs, or even performance optimization for general case. That all takes
different design decisions than the personal preferences of its designers when
building on Richards' work. It was also achieved by Wirth shortly after to
point that C's remaining benefit could've been had as an option or tweak to
Wirth's approach. Easier to tweak his for C's benefits than vice versa since
his was actually designed and simple. Final proof of that was when C's
inventors did that in their ideal language: an Oberon-2 improvement called Go.

"Thus Rust can start eating C/C++'s lunch, and people will stop using C for
what it does badly, and using it for what it does well"

This is true. Again, though, due to social reasons more than tech. People been
able to do that with GPL'd Ada. Rust takes off, though. The likely reason is a
combo of developers preferring its syntax/semantics, how the community runs,
and primarily Mozilla's effort [like Sun's Java & Microsoft's C# before it].
Like with the Richard Gabriel and the startups, details of execution matter
more than how great the idea is.

~~~
qwertyuiop924
>It's closer to an optimal solution if you're squeezing max performance out of
old hardware with a higher-than-assembly language.

That was what was happening when C got popular.

~~~
pjmlp
Depending on the OS.

On MS-DOS, there was hardly any difference between the code quality generated
by the Borland C and Pascal compilers.

~~~
qwertyuiop924
But by that time, C was already very popular.

~~~
pjmlp
Not really.

I only bothered with C in 1993, yet I started coding in 1986, used Turbo
Basic, Turbo Pascal 3, 5.5 and 6.0, alongside TASM before that year.

Similar experience to many other Portuguese fellow coders.

We only bothered with C either at the university level or because some had
access to UNIX at work.

My first UNIX experience, the teacher carried a PC desktop with Xenix into
class and we would take turns to use it.

~~~
nickpsecurity
I also think you might need to separate the circumstances of Portugal from
UNIX and C in general. Same with other countries. I'm curious how much it
spread in general versus other solutions plus at organizations with enough
influence to determine a victor. I think Portugal's case is the rare one here.

~~~
pjmlp
Might be, but on those days there was hardly any usable data to validate this,
so we are left with personal experience.

------
tinco
For me the main selling point is that it allows me to do code with performance
constraints without having to resort to a programming language without modern
package management, modern documentation or a modern ecosystem.

I would have jumped at any chance to do modern programming that way, and dodge
C and C++.

It is a double blessing that besides satisfying these rather basic
constraints, it's actually a great programming language as well, improving
safety and reliability, having a concise but expressive syntax, a powerful
type system, even a novel solution for enforcing some safety in shared memory
situations.

------
empath75
I've done some rust tutorials, and I think the language is really interesting,
but the reason I've never used it is I don't know what I would use it _for_ ,
other than system programming.

I've never had a work related problem where I searched for a way to solve it,
and someone had said: "Oh, if you use rust it's easy, because of x,y and z."

I'm sure if I were writing something like sshd from scratch today I'd use
rust, but other than system-y sorts of applications like that, I don't know
what I'd use it for.

~~~
stymaar
I can relate to this. I'm a web developer and Rust (mostly the ecosystem) is
not ready for web dev (the future look bright though, tools like Diesel[1] or
Rocket[2] looks incredibly promising).

I recently found a place where Rust really shine : CLI tools. Rust multi-
platform story is great, and the clap[3] crate makes it really straightforward
to create helpful CLI tools. The blog post «Using Rust for scripting»[4] is
really insightful in this regard. Now I use Rust any time I would have use
Ruby to automate stuff with a little script. It's obviously more verbose, but
the type system and error-handling story helps a lot.

[1]: [http://diesel.rs](http://diesel.rs) [2]:
[https://rocket.rs](https://rocket.rs) [3]: [https://clap.rs](https://clap.rs)
[4]: [http://www.chriskrycho.com/2016/using-rust-for-
scripting.htm...](http://www.chriskrycho.com/2016/using-rust-for-
scripting.html)

------
jondot
Hi Steve,

We've met at Rails conf, in Tel Aviv many years ago. You seemed nice, so I'm
motivated to try to give you my 2c.

I believe Rust _can_ be more than safety but right now it isn't as you are
imagining it.

I've started off in the demoscene in the early 90's, and so I've had my share
of assembly, C, and C++ as a kid. I've built demos, games, generative 3D art
with 8-64kb executables, without access to Internet or any form of proper
knowledge, and it's funny how scared I am of attempting this again today when
I'm much older, and much, much more experienced. I think one of the scary
factors are the time-to-value ratio: I'm used to several orders of magnitude
more productivity, and have much less time.

I think the most important take away from my background story that you can
adopt is - make Rust playful. Fun is a a base element for curiosity, it what
drives us where we're the most receptive - when we're kids - to learn, to
experience, and to understand what will in be our toolbelt for the next dozen
years.

Make rust playful. Make a game framework. Make it build on a mobile device.
Make it build on a Pi (without docker, and the entire diarrhea of toolchain
you have to use). Make it build for the Arduino. Cross compile it to
Javascript (for fun!).

Often I try my hands at C and C++ again. When I do that, I'm not disappointed.
I see a comforting place where I've spent my childhood at (and with C++ - some
of my professional life). I'm happy with how C++ evolved and how CMake works.
I'm not happy because productivity didn't change for the better that much. It
still requires around the same amount of time to build things in C and C++ as
it did years ago.

Where I do see a change is with Go. It gives me the same comfort, with an
insane productivity factor. It also had fun baked in from the start - it can
run on mobile, it can run games, and it can compile to what ever I want
without a fuss.

I hope my thoughts will make a real change. I really do think this is the
missing part with the Rust story.

~~~
jamesmunns
Hey Jon,

Not Steve here, but I was wondering if you were being sarcastic here:

> Make rust playful.

Why am I asking if you're being sarcastic?

> Make a game framework

[http://www.piston.rs/](http://www.piston.rs/)

> Make it build on a mobile device

[https://www.bignerdranch.com/blog/building-an-ios-app-in-
rus...](https://www.bignerdranch.com/blog/building-an-ios-app-in-rust-part-1/)

> Make it build on a Pi... without diarrhea
    
    
        curl https://sh.rustup.rs -sSf | sh
    

> Make it build for the Arduino

(An ARM based Arduino, AVR [which powers the original Arduinos] support is
being worked on now)

[https://github.com/jamesmunns/teensy3-rs](https://github.com/jamesmunns/teensy3-rs)

> Cross compile it to Javascript

[https://blog.rust-lang.org/2016/12/22/Rust-1.14.html](https://blog.rust-
lang.org/2016/12/22/Rust-1.14.html)

~~~
jondot
I'm not being sarcastic at all, and after reading my post again I can't see
how it can be read that way. My apologies if my english isn't that good.

I'm familiar with piston, and by "making it build on a Pi" \- my mistake, I
meant make it cross-compile for a Pi. The rest of your examples are quite "it
can be done" and not it "should be done".

The only thing I can say is - why not organize a game competition around
piston? I'm sure Mozilla has the funds. This is what I mean by make it fun and
make a game framework. I'm sure that other than piston you could find other
Rust game frameworks but i'm sure you can't find one that's as accepted as
PyGame or LOVE, and then, Cocos2d-x C++ port is being pitched "for
performance", and why can't that be Rust?

------
bmalehorn
I am a systems programmer working at a company with a largely C++ codebase. We
don't use Rust.

It has nothing to do with the reasons mentioned in the article or this thread.

Here are a list of requirements for us to use Rust:

    
    
      - Does it support all of the following architectures? x86_64, ARM, MIPS, powerPC
      - Does it support soft float?
      - Can it link against uclibc instead of glibc?
      - Can it link against arbitrary C libraries?
      - Can I use a C library's header.h file without having to hand-recode it to Rust?
      - Will the code I write now continue to compile 5 years from now?
    

Does Rust score a resounding "YES" on ALL of the above questions?

~~~
dikaiosune
It mostly scores a "YES", where there are footnotes. AFAIK all of these things
are being worked on.

> Does it support all of the following architectures? x86_64, ARM, MIPS,
> powerPC

It does: [https://doc.rust-lang.org/book/getting-
started.html#tier-2](https://doc.rust-lang.org/book/getting-
started.html#tier-2). Granted, while tier 2 support is pretty good, it isn't
the same level of support as the tier 1 platforms.

> Does it support soft float?

From running `rustc -C help`:

    
    
            -C            soft-float -- use soft float ABI (*eabihf targets only)
    

> Can it link against uclibc instead of glibc?

It can link against musl, but I'm not sure whether that would enable uclibc.
Probably?

> Can it link against arbitrary C libraries?

Yes.

> Can I use a C library's header.h file without having to hand-recode it to
> Rust?

You can use something like rust-bindgen ([https://github.com/Yamakaky/rust-
bindgen](https://github.com/Yamakaky/rust-bindgen)) which will work with a
minimal amount of cleanup afterwards in my experience. Still not a resounding
yes, though.

> Will the code I write now continue to compile 5 years from now?

Yes. See [https://blog.rust-
lang.org/2014/10/30/Stability.html](https://blog.rust-
lang.org/2014/10/30/Stability.html) for more about the plans/policies/etc.

~~~
bmalehorn
Great, thanks for the reply and links.

Sounds to me like the current state is "doable," but not "solid." I can
convince myself to try it out, but not my whole company. But, maybe this will
improve over time.

~~~
dikaiosune
That seems like a fair summary to me. Several of these items (better interop
with existing libraries, for example) came up in the recent 2017 roadmap RFC
conversation, and I would expect them to improve in the future.

Also, if you do try Rust and find other issues that would be blockers for your
company to pilot a project, I know that the teams have been very eager to get
feedback from "systems" shops on what would be needed to get them trying Rust
out commercially.

------
pornel
For me the best thing about Rust is that I can create beautiful APIs that are
hard to misuse.

With ownership rules I can enforce logic of _how_ my API is supposed to be
used, e.g. "you can call this method only once", "you can use that object only
until you call destroy() on the parent" can be enforced at compile time. Same
with levels of thread-safety of my code. Users of my libraries don't need to
RTFM to use them correctly.

------
pjmlp
Personally I don't have any use for Rust, other than occasionally dabbling on
it, but I look forward to its adoption.

Because Rust appears to be one of the ways for newer generations to rediscover
how systems programming was done in safer systems programming languages before
UNIX alongside C, enjoyed adoption across the industry.

Also due to all the work on ownership management, that has already influenced
future design decisions on C++, Swift, D, ParaSail and Pony.

And eventually with time, even those of us that don't use it, might enjoy
having a safer stack to work with.

------
Ar-Curunir
I like how "high level" Rust feels. It doesn't feel like C or something of
that ilk.

~~~
vvanders
Yes, the relentless focus on zero-cost abstractions is fantastic.

~~~
lngnmn
Could you, please, elaborate. In my opinion _zero-cost abstraction_ is nothing
but a catchy meme.

Could you provide an example, so I would try to implement such a wonder in one
of classic languages I know, like SML or Scheme?

~~~
steveklabnik
A simple one is Option. An Option<&T> is a pointer to some type T. Option is
an enum, & is a reference, which has all of Rust's safety checking. This will
all compile down to a regular old pointer, just like in C. Even though you
have null checking and protection against dangling pointers, etc. It's all at
compile time, zero run-time overhead.

~~~
lngnmn
So, typed pointers with an analog of the option type. Thank you.

Could we say that Swift or even SML with typed refs has similar safety and
zero-cost abstractions?

~~~
kibwen
Determining whether an abstraction is zero-cost or not is often buried deep in
a language's implementation, so you'd need an expert to determine whether a
given abstraction in Swift or SML qualifies. But regarding closures
specifically, I can say that it's very unlikely that either Swift or SML have
a zero-cost implementation, since having stack-allocated closures is an
immense and deliberate decision in language design (AFAIK only C++ and Rust do
this).

------
rcthompson
> Rust is] Technology from the past come to save the future from itself

So Rust is the Terminator but in reverse.

------
steveklabnik
This blog post was inspired by this comment:
[https://news.ycombinator.com/item?id=13266627](https://news.ycombinator.com/item?id=13266627)

------
softc
A language's error-handling story is a central part of the experience of using
that language. _Especially_ if that language is a systems language.

Rust's error handling still seems unnecessarily verbose to me. A specific
error type is only necessary if the program can handle the error in question.
Rust has acknowledged this but I still don't want every function call in my
code to be prefixed with "try!" or suffixed with "?!"

Rust error handling is also inefficient: in C++, if no error happens, then no
code is run, whereas in Rust, even if no error happens a return code must be
checked.

I will sadly continue to happily use C++ until Rust improves its error-
handling story.

~~~
akiselev
_> Rust error handling is also inefficient: in C++, if no error happens, then
no code is run, whereas in Rust, even if no error happens a return code must
be checked._

Just because you don't have to write the code doesn't mean that it doesn't
exist! Exceptions are not a zero cost abstraction. Every C++ functional call
that can throw adds several instructions of overhead to save information about
the call stack and check the return value so even when you don't have an
exception you still have the _same_ amount of overhead as all Rust errors.
Options are simple types that can often be optimized to the size of T in
Some(T) and they're on the stack so worst case is you need an extra usize slot
in your stack.

In the case of success, Rust is at least as efficient with errors as C++ but
far more efficient when errors do occur.

~~~
softc
In C++ with the Itanium ABI, exceptions only add overhead when thrown, not on
every function call. In Rust, the result of every function call is checked.

~~~
Gankro
Agreed on this, but this is ignoring the much more subtle effect of unwinding:
it introduces optimization barriers around every function that "might" throw.

As a basic example:

    
    
        x = 1
        something_that_can_fail()
        x = 2
    

With unwinding, the `x = 1` write must be preserved if whoever catches can
observe it (and if that's unclear, it must be preserved conservatively).

The C++ STL riddled with complex machinery to try to work around this sort of
thing because _everything_ can throw. Copies, moves, you name it! Not even
reallocating an array can be done with realloc unless non-throwingness can be
proven.

If you try to make throwing "opt in" like Java, then you end up with nasty
"throwingness polymorphism" problems and end up with constructs like Swift's
"rethrows". By contrast, error propagation through normal values naturally
composes because it's really easy to write code that generically handles
return values.

~~~
softc
Good point. Some responses:

Function calls themselves can force something like "x = 1" if x is observable
from the callee.

In the case where "x = 1" is not observable from the catch block, then there
is no effect. In cases where you would use "try!" in Rust, in the equivalent
C++ cases the catch block wouldn't be able see local variables since it would
be in a parent function call.

I think LTO largely eliminates this issue altogether since function bodies are
visible to the optimizer in that case.

------
dispose13432
You know what I would like? (Yeah, speaking of entitlement :) )

A "safe C". No classes, no functional programming (except function pointers,
maybe anonymous functions), no exceptions, just plain C but

1\. memory safe 2\. optional array overflow detection (possibly unset by an
operator in code, so [] is safe, but a^[] is unsafe. It's nice so if you
_really_ need speed in a certain block and you know it's safe, you can turn it
off).

Maybe something like Go but with "manual" (c++ safe pointer style) memory
management.

Rust seems (to my untrained eye) too similar to C++ (it's quite a
complicated/powerful language).

~~~
zzzcpan
There are safe C dialects already. The problem is they are not compiling into
C, so you can't leverage the whole C ecosystem with them. Although I would
suggest a different road - C code generation with meta languages, you'll get
all the benefits of C with total control and all the high-levelness and safety
you might need.

~~~
nickpsecurity
I second that recommendation. It's what PreScheme, Ada, Chicken, and Nim did
among others. All brought benefits in practice.

------
mmstick
I typically explain that Rust's safety has side effects that are beneficial
outside the obviousness of merely being safe. Namely, Rust's safety allows for
migrating runtime checks into compile-time checks when constructing state
machines around the ownership mechanism. Additionally, Rust's safety allows
for additional compiler optimizations, because that safety can make more
guarantees about the safeness of certain internal compiler flags. These have a
speed benefit in addition to the already existing convenience benefits of not
having to fight with broken code. I'd much rather fight a borrow checker than
to fight through gdb's and lldb's to figure out why everything's totally
broken.

Then I go on to explain that there's a lot of great features in Rust that make
it more convenient than C/C++ in a wide range of general purpose programming
tasks. The pattern matching, sum types (Option/Result), error handling
strategy, and my favorite, the Iterator trait.

For the performance-minded C/C++ software developers, I explain that the
safety that Rust provides via lifetimes and ownership allows me to comfortably
perform extreme performance optimizations that would otherwise be incredibly
nasty and error prone in C/C++ codebases. I can feel safe knowing that if it
compiles, it's almost always going to work how I expect.

Then there's the whole test-driven development mentality to Rust software
development that Rust provides with `cargo test` and `cargo bench`, and data-
oriented programming approach that Rust takes versus the inferior object-
oriented approach via protocol-oriented programming (traits) to feature ad-hoc
polymorphism and generics. It's a bit more complicated to explain that though.

Then there's the whole community/tooling/documentation pitch. I think this is
one of the more important aspects of Rust as it demonstrates that Rust has a
future and is more than just a niche. It has momentum which cannot be
destroyed. It's a language invented during the age of the Internet and takes
full advantage of that.

Rust does not employ guerrilla warfare tactics like other languages have done
in the past. You can think of C/C++/Java/etc. as long-running empires.
Guerrilla warfare-style tactics simply don't work against them. Emerging
languages have always targeted C/C++/Java/etc. through guerrilla warfare
tactics -- a loose community that mostly does their own thing. Rust is
ambitiously establishing an empire of it's own through it's community -- a
plethora of official projects and services: rustup, cargo, crates.io, docs.rs,
users forum, internals forum, reddit thread, official documentation, docs
team, an official book, GitHub hosting, etc. It's a recipe for success.

------
fjrieiekd
I love Rust and I've been following it for a while now, hoping to use it more
in my line of work. However, I still find that support for Rust on Android and
iOS is still lacking, compared to C and C++. These platforms are technically
supported, but they aren't tier one and don't seem to be widely used.

This doesn't matter that much for hobby programming, but for production work
I'd be happier if there was a clear and easy path for adding Rust to the build
system, and having the tools integrate into my chain, with great support for
debugging and testing. I'm happy to deal with the extra work myself when I'm
doing it for fun, but otherwise, compared to the first class support in Xcode
or even the NDK, Rust is still far behind.

For me to feel comfortable in taking the risk in choosing a non-vendor-
sponsored language like Rust, I need to be confident that my tools will work
and won't break on me, integrate poorly or fail in unexpected ways. If Rust
was on par with C/C++ support, it would definitely be a very compelling
solution.

------
accurrent
The main problem for rust that comes to mind is the already huge codebase
written in c. Personally I tend to use opencv and openssl a lot. I know there
are rust wrappers around openssl and opencv it would be nice to see pure
implementations. I think an application like tls would benefit from rust a
lot.

There are other things like advanced static analyzers such as frama c which
exist only for c. Similar tooling would be helpful for rust.

Then there's of course embedded where rust could really shine. However llvm
doesn't have backends to many of the 8bit architectures. Furthermore industry
standards such as misra c dont seem to have rust equivalents, although rust
may be better suited for safety critical code.

Finally, explaining the need of a borrow checker to a beginner is very
difficult unless they already have experienced enough pain with segfaults. It
took me ten minutes with a pen and paper to explain pointers to my 12yo
brother. How can I explain the need for all of rusts safety checks unless he
has experience with segfaults. Any suggestions here would be welcome.

~~~
steveklabnik
> the already huge codebase written in c.

This is something you can work with!. A big example happening right now is the
work going on in the GNOME project.

> I think an application like tls would benefit from rust a lot.

[https://crates.io/crates/rustls](https://crates.io/crates/rustls) still has
some C at its core, in _ring_ , but it will be eventually.

> Similar tooling would be helpful for rust.

Rustc already does a lot of things this kind of tooling does. More tools are
good though!

8 bit is far off. Teaching is hard. I don't have easy answers for those ones
:)

------
agentgt
Interestingly OCaml is 1996 (which is the language the original Rust compiler
was written in). Maybe access to faster internet connections caused the rapid
language explosion (I remember broadband cable starting to be available at
that time)?

------
EwanToo
I haven't fully thought this out yet, but it strikes me that with an AWS SDK,
Rust would be an ideal language for high performance Lambda functions.

* No JVM/Interpreter memory overhead * No garbage collection (I know this is controversial) * Compiled binaries with low startup time * High performance (assuming you write it well..) * Aware of multi-core systems * Good networking capabilities

Currently if you want really high performance on Lambda with a SDK for AWS
services, you have to go Java and all that comes with it, or launch Go or C++
binaries via a nodejs process.

~~~
steveklabnik
[https://crates.io/crates/rusoto](https://crates.io/crates/rusoto) is one of
the bigger AWS SDK crates. There's been some interest in Rust on Lambda, but I
forget if there's a tutorial or something.

------
catnaroek
To me, _any_ language is two things:

(0) How easy it is to write a program that just does what I want.

(1) How easy it is to avoid writing a program that seems to do what I want,
but doesn't.

Rust already scores highly in (0), but it truly excels in (1). Beating Haskell
and ML at their own ”it compiles, it works” game is no small feat.

As for whether GC or no GC, most of the time I don't really care either way.
Garbage collection is incredibly helpful, but so is Rust's particular brand of
resource management. As long as there is neither memory corruption nor
resource leaks, I'm happy. :-)

------
newsat13
> The second is that, other than C# in 2000, 1995 or earlier is where most of
> our programming languages come from. Have we really not made any
> advancements significant enough in the last 20 years to have gotten people’s
> attention?

This is like saying the bicycle was made in 1900 and modern bikes are the
same. Has nothing changed in 100 years? Change for the sake of change is
unnecessary and it most cases detrimental to the core product. Fact is that
languages like PHP, Ruby and JavaScript are simple enough for most people to
get their jobs done (read: 90% of all programming jobs) and to me this is the
only requirement for a general purpose programming language.

From a marketing point, rust needs to decide if this is for the power
programmer or not. For example, Go has taken the niche of easy to understand
and won't complicate life by adding unnecessary features so that it can
pretend to be "modern" (I am looking at you ES6/7). Rust needs to understand
that it simply cannot replace Ruby/PHP or JavaScript. It is not easy to
understand and it's super power is simply not required for most programming
tasks.

My understanding is that it is meant for systems programming and this means
that it should target C/C++ and stop comparing itself with scripting
languages.

~~~
steveklabnik
I think the bike analogy is a great one: yeah, today's bikes basically _are_
the same as 1900's bikes. Sure, you can get carbon fiber whatever, and there's
been some small advances, but they're still pretty much bicycles.

In this analgoy, I'm suggesting that cars aren't really in widespread use yet.

~~~
akiselev
I don't like this analogy as much as you because it misses a hundred years of
industrial innovation that took the bike from a novelty to the most common
form of assisted transportation on the planet. Rust isn't the bike, it's the
factory that was built with the best manufacturing techniques from dozens of
other factories combined into one. A bike (the software you're trying to make)
is still a bike no matter who makes it but this new factory can make them
safer, faster, and cheaper.

~~~
steveklabnik
Possibly :) Analogies are hard.

------
komali2
I haven't found any reply blog posts yet but I'm curious about rust. Has
anyone found a response to the call to action at the bottom of the post?

~~~
masklinn
> Has anyone found a response to the call to action at the bottom of the post?

The post was published ~1h ago according to the author's twitter
broadcast/alert[0], so there probably aren't any lengthy responses yet (even
the twitter responses have nothing).

[0]
[https://twitter.com/steveklabnik/status/814165927478652929](https://twitter.com/steveklabnik/status/814165927478652929)

------
ue_
Can someone tell me how this language is supposed to be any degree of 'safe'
when things like this compile (without warning, on Nightly rustc) and "panic"?
Rust is about as safe as C.

    
    
        fn main() {
            let a = 4;
            let v = [0,1,2,3];
            println!("{}", v[a]); 
        }
    

result:

    
    
        rustc 1.15.0-nightly (71c06a56a 2016-12-18)
    
        thread 'main' panicked at 'index out of bounds: the len is 4 but the index is 4', <anon>:4
        note: Run with `RUST_BACKTRACE=1` for a backtrace.

~~~
C4K3
Note, I get warning: this expression will panic at run-time when compiling it,
but that's besides the point.

Panicking is exactly what makes it memory safe, it doesn't access any out of
bounds memory. Write an equivalent program in C, and nothing will error, but
instead will output something like 140733019311920. Which of those is
preferable?

~~~
ue_
What code did you use to make it print that error? I only get that error if I
access the array directly with a subscript (i.e using the constant 4 instead
of 4 stored in the variable 'a').

~~~
steveklabnik
Yes, the warning is very limited at the moment.

------
frozenport
C++17: 2016

