
Rust 1.17 - steveklabnik
https://blog.rust-lang.org/2017/04/27/Rust-1.17.html
======
GoodbyeEarl
Hey, folks! I have never used Rust but all the buzz around it made me curious,
so I may ask you to forgive my ignorance on the matter. I have a few honest
questions about it and I'm pretty sure these questions were answered before,
so feel free to point me to this resources, I'd appreciate very much.

First of all what's the point of Rust? OK, it's a systems language, but what
does that even mean? You can write a system in any language right? Python is a
scripting language and lots of people use it everyday to write systems. What
problems is it trying to solve? Also how does it compare to Go? (I haven't
used either one or another). It seems to me that both Go and Rust are mainly
used by C/C++ folks that want a new shiny language that somehow resemble the
syntax or structure or funcionality of the former and at the same time add
some modern features (I might be totally wrong by presuming this).

From the perspective of other languages I know a little bit such as Ruby,
Python or JS its syntax seems really bloated to me with all those specials
symbols. Do you feel more productive writing software in it than in let's say
JS? Please keep in mind that I really don't know Rust (nor I've never tried a
statically-typed language) and I don't mean to offend anyone.

Thank you guys!

~~~
l1ambda
Because you can build things like:

* A faster grep ( [https://github.com/BurntSushi/ripgrep](https://github.com/BurntSushi/ripgrep) )

* A GPU accelerated terminal emulator ( [https://github.com/jwilm/alacritty](https://github.com/jwilm/alacritty) )

* A web browser ( [https://servo.org/](https://servo.org/) )

* A containerization system ( [https://github.com/tailhook/vagga](https://github.com/tailhook/vagga) )

* An operating system ( [https://github.com/redox-os/](https://github.com/redox-os/) )

* An extremely fast text editor ( [https://github.com/google/xi-editor](https://github.com/google/xi-editor) )

And be faster and safer than C/C++.

~~~
dronemallone
Is there a reason why all the above software cannot perform as "fast" or
"safe" as Rust when written in other programming languages? After all, every
program compiles down to machine code/assembly.

~~~
btown
As soon as you need to be able to access low-level pointers for performance,
you run into a problem: you can easily end up holding onto a reference to
memory that's been cleared, or otherwise invalidated, by some other piece of
code. This type of bug is insidious, and can easily be missed by the most
stringent unit tests and even fuzzing. Of course you can try to get around
this with abstractions on top, as every higher-level language does, and as you
can do in C++ if you're willing to build reference-counted pointers around
_absolutely_ everything... but these are not _zero-cost_ abstractions.

What Rust does is track reference lifetimes at compile time, giving you
certainty about who can safely "own" or "borrow" memory in every single line
of code, without any runtime pointer indirections or other slowdowns. The
language is built around this feature at every level, with "lifetimes" being a
syntactic construct at the level of type and mutability.

Imagine if you wanted to safely parse user-submitted JSON, maybe cache derived
products from that JSON, and then make sure that when the input buffer is
released, you weren't holding any handles into strings inside it. The only
safe way to do that in any other language is to proactively copy the strings,
or rigorously reference-count the input buffer. But Rust has your back here.
If you use zero-copy deserialization from Serde ( [https://github.com/serde-
rs/serde/releases/tag/v1.0.0](https://github.com/serde-
rs/serde/releases/tag/v1.0.0) ) then the compiler will refuse to compile if
you are using any of that data longer than the lifetime of the original
buffer, and do so without needing to add any runtime bookkeeping.

Yes, it's an annoying language to learn because of that "fight with the borrow
checker." I LOVE that the language designers and steering committee are so
open to quality-of-life improvements for newbies, like that string warning.
The language will only get easier to learn over time. It may never be what you
use to make your next app, but if you're doing systems programming, it's the
wave of the future.

~~~
wmertens
So, I recently saw a study claiming that memory management-related issues
constituted 25% of attacks, the rest was other vectors. I may be
misremembering, but in any case, simply getting rid of memory faults does not
get rid of all attack vectors.

Given this, I wonder if the (seemingly) added complexity of Rust could result
in more attack surfaces of other kinds.

I don't know anything about Rust mind you.

------
kibwen
Hard to believe that this is the 17th minor release since Rust 1.0. :) Lots of
good ergonomic improvements in this one, but for those of you who are itching
for incremental compilation, a beta is now available for testing using the
CARGO_INCREMENTAL environment variable: [https://internals.rust-
lang.org/t/incremental-compilation-be...](https://internals.rust-
lang.org/t/incremental-compilation-beta/4721)

~~~
TylerE
Why is it so hard to believe? Don't they release a new version every month
like clockwork?

~~~
kibwen
It's every six weeks rather than every month, and the fact that it's like
clockwork is what's so impressive! I've actually implored the Rust devs before
to slow the release cycle for their own sake, it seems to be quite brutal.
They must be masochists, because at least some of them have told me they enjoy
it. :)

~~~
pdpi
There's a lot of "not finished so wasn't included in this release" in the
release notes.

With, say, a 12 week cycle instead of 6 weeks, I'm waiting 3 months for My
feature to land in the next release, and I feel a lot more pressure to get it
done _now_ than I would with a 6-week cycle where missing a release isn't a
big deal.

Assuming the team has the release process we'll automated and cutting a
release doesn't add a lot of work, then there's not much to lose with this
cycle.

~~~
user5994461
Missing a release should never be a worry. People can always wait.

having stable release with no regression > releasing fast

~~~
dbaupp
"should" is a nice ideal, but people will feel pressure, especially for
tooling like a compiler that other teams depend on, where slipping schedule
means slipping their schedule too. Shipping more often lessens this, by
meaning a missed release costs much less time.

Empirically, Rust has done a pretty good job of shipping fast and not
releasing regressions, so it seems like this isn't mutually exclusive.

~~~
majewsky
I think that those few people who rely on the newest-possible features in the
compiler will be compiling with a nightly build anyway (possibly pinning to a
known-good version until the next release).

That's actually somewhat a meme within Rust, at least as far as my impression
from the outside goes. There apparently were times where most interesting
crates required some unfinished feature and thus a fairly recent nightly build
of the compiler and/or Cargo. I believe that problem has decreased in the
meantime, but as I said, I'm looking into Rust from the outside only and don't
have much own experience.

~~~
dbaupp
According to the developer survey last year, most of the community is using a
stable compiler in some form[0]. I can only imagine that the ratio has
improved since then, especially with custom derives in 1.15. Additionally, I
semiregularly see people say that they don't use nightly in production, even
if they're using it for preview/experiments/testing.

[0]: [https://blog.rust-lang.org/2016/06/30/State-of-Rust-
Survey-2...](https://blog.rust-lang.org/2016/06/30/State-of-Rust-
Survey-2016.html#using-rust)

------
kevindqc
> String concatenation appends the string on the right to the string on the
> left and may require reallocation.

I don't really know Rust, but isn't that weird? In most languages I know, I
would expect for example Vector3(1, 2, 3) + Vector3(2, 3, 4) to return a brand
new Vector3(3, 5, 7), with Vector3(1, 2, 3) unmodified? Unless I do vector1 +=
Vector3(2, 3,4), at which point I expect vector1 to be modified without
creating a new vector?

Why doesn't rust create a new String and concatenates using this new owned
String? I guess that's why beginners get it wrong - I would

~~~
steveklabnik
So I should preface this by saying that the Add impl was generally
controversial and almost not even implemented, but ended up happening.

In a systems language, allocations matter. As such, people are generally
really against hidden allocations in Rust, moreso than in other languages.
This totally could have been done, but by requiring a String on the left, you
are already in "this is heap allocated" land, and that is much more palpatable
for Rust's audience.

~~~
eduren
>palpatable

=palpable + palatable. Pedantry aside though, I like the word. Maybe it
describes something can be palpably palatable.

~~~
steveklabnik
Ha! Nice catch. Good thing I'm not like, a person who's paid to write words or
anything...

~~~
chrismorgan
You wrote a word! A _new_ word!

------
daliwali
I was interested in learning Rust as a safer alternative to C a few years
back, and have been observing its progress from afar. I'm much less optimistic
about it now, though I only have a layman's understanding of it. The language
seems to be more cumbersome to write than many other languages due to its
design choices. It may be safer, but not as "ergonomic" subjectively, which
ultimately affects productivity. It's hard to think of a good reason to use
it, other than the safety features.

~~~
w8rbt
I agree 100%. The Rust syntax is so different from C, C++, Go and Java that
it's very difficult for me to use. I love the idea of Rust, but I wish the
syntax was more similar to traditional languages. If it were, I think it would
be a very easy transition for many of us.

~~~
zanny
A lot of the compromises made in Rust syntax were to make it much, much easier
for the compiler to reduce passes to compile into a syntax tree.

There are certainly some things that should just be obvious now, though. Using
the C++ namespace separator of :: is just ludicrously obtuse for an extremely
common symbol, using the & for refs is archaic (I mean... you could have just
called it a ref. ref T instead of &T. And then just ref(foo) or foo.ref to get
a ref to foo.) And the syntax for lifetimes is horrible, with the 'a and the
fact that in practice its about as significant as naming parameters in a C++
function definition in a header (ie, pointless - the words are discarded by
the compiler every time).

And I certainly would have argued for whitespace significance, at least as an
option, instead of classic semicolon spam.

Given all that, Rust is still, IMO, the best programming language we have
right now for native performance, period. We can criticize what we don't like
but we should at least agree its the best we have.

~~~
kbenson
> Using the C++ namespace separator of :: is just ludicrously obtuse for an
> extremely common symbol

Obtuse? It's sort of common. Multiple languages use it. Personally I like the
namespace separator being distinct from the object/struct element accessor. At
least they didn't copy PHP in using backspace...

> using the & for refs is archaic (I mean... you could have just called it a
> ref. ref T instead of &T. And then just ref(foo) or foo.ref to get a ref to
> foo.)

Please, let's not have more cases where things look like functions but aren't.
Functions should look like functions. Operators should look like operators.
You might have to learn a small set of operators for a new language. This is
front-loading some confusion and learning pain for ease of use later. It may
make the language harder to read _for people that don 't know the language_,
but anyone reading the source code with the aim to make some changes should
probably know the operators at least. I'm not sure giving it a slightly more
expressive name but making it look like something else actually makes life
easier for those people.

> And I certainly would have argued for whitespace significance, at least as
> an option, instead of classic semicolon spam.

 _Optional_ whitespace significance? That sounds like a recipe for disaster,
IMO. I can see a case for one or the other, but mixing of modes like that when
it deals with something that is by nature somewhat invisible (or meta), seems
prone to problems.

Also, examining why Python has had problems with functional style workhorses
like map might shed some light on the negative aspects of whitespace dependent
syntax.

~~~
zanny
Commonality doesn't make a shift-accessible character twice in a row less
obtuse. It is like if < and > were the bitwise shifts and >> and << were the
logical - it would make no sense because the more common behavior was using
more characters.

Of all the glyphs used in the language, :: is probably in the top 5 for
frequency of use (probably higher than even * in Rust, considering the
infrequency of pointer usage and that multiplication isn't _that_ common an
operation in general code) but uses two glyphs instead of one.

It would have required different design constraints starting out to figure
which glyph would be best suited instead of ::, but :: is still really ugly in
all the languages that use it when its such a common symbol. I wouldn't argue
overloading . is right, but I'm having a hard time seeing why a single colon
doesn't work - foo:bar:baz. Maybe the parser finds scoping and explicit type
names on definitions (ie let foo: i64 or in function definitions) require too
many passes to distinguish?

~~~
kbenson
Valid points. A single colon would suffice, but I suspect in C++ they wanted
something a bit more distinct from the semicolon. For Rust, I imagine at least
part of the reasoning was keeping with what was familiar wit h C++, and after
that the type names probably did make it complex, if not intractable (without
reserving specific names).

------
Animats
Tried some programs that used to work:

First program:

    
    
        src/main.rs:65:11: 65:19 error: no method named `join` found for type `collections::vec::Vec<&str>` in the current scope
        src/main.rs:65     sline.join("")                              // return string
    

OK, what happened to ".join", and who had the great idea of taking it out?

Second program:

    
    
        $ cargo build
        An unknown error occurred
    
        To learn more, run the command again with --verbose.
    

OK, must rerun because of useless message.

    
    
        $ cargo --verbose build
        Invalid arguments.
    
        Usage:
            cargo <command> [<args>...]
            cargo [options]
    

Note that the "Usage" message doesn't say where to put the options if there's
a commmand. So we have to guess:

    
    
        $ cargo build --verbose
        Failed to parse registry's information for: chrono
    
        Caused by:
          the given version requirement is invalid
    

The version requirement in the cargo.toml file under [dependencies] is

    
    
        chrono="*"
    

which, according to this manual [1] is valid.

I used to like Rust, but after years of stuff breaking with each new release,
I don't use it for anything serious.

[1] [http://doc.crates.io/specifying-
dependencies.html](http://doc.crates.io/specifying-dependencies.html)

~~~
Manishearth
Rust has not removed an API since 1.0. Your code is extremely old and predates
stability.

Yes, star dependencies were removed like a year ago, for semver issues. They
went through multiple release cycles of warnings.

~~~
Animats
_Rust has not removed an API since 1.0. Your code is extremely old and
predates stability._

That code worked through at least Rust 1.2. So, yes, Rust _has_ removed an API
since 1.0. That code was compiling in December 2016.

 _Yes, star dependencies were removed like a year ago, for semver issues. They
went through multiple release cycles of warnings._

From the Cargo manual [1]:

    
    
        Wildcard requirements
    
        Wildcard requirements allow for any version where the wildcard is positioned.
    
        *, 1.* and 1.2.* are examples of wildcard requirements.
    
        * := >=0.0.0
        1.* := >=1.0.0 <2.0.0
        1.2.* := >=1.2.0 <1.3.0
    

Apparently, nobody bothered to update the manual after removing the feature.

[1] [http://doc.crates.io/specifying-
dependencies.html](http://doc.crates.io/specifying-dependencies.html)

~~~
steveklabnik
To be clear, you can use star dependencies locally, but pushing a new crate to
`crates.io` will reject crates that have star dependencies. So in some senses
this is still accurate, but it's missing the crates.io interaction.

This means I don't understand how you got your error. For example:

    
    
      > cat .\Cargo.toml
      [package]
      name = "star"
      version = "0.1.0"
      authors = ["steveklabnik <steve@steveklabnik.com>"]
      
      [dependencies]
      semver="*"
      > cargo build
          Updating registry `https://github.com/rust-lang/crates.io-index`
         Compiling semver-parser v0.7.0
         Compiling semver v0.6.0
         Compiling star v0.1.0 (file:///C:/Users/steve/tmp/star)
          Finished dev [unoptimized + debuginfo] target(s) in 5.24 secs
    

I've filed [https://github.com/rust-
lang/cargo/issues/3971](https://github.com/rust-lang/cargo/issues/3971)

I'm also not sure how you got your `join` error,

    
    
        let sline: Vec<&str> = vec![];
        sline.join("");
    

seems to compile just fine for me. Hard to tell without seeing your other
code, I guess...

~~~
Animats
The Cargo problem turns out to be a known incompatibility between the version
of Cargo which ships with Ubuntu 16.04 LTS and later version of Rust.[1][2][3]
"Old versions of cargo cannot install any version of a crate that has a
version with a prelease string". It's not the user's .toml file that's the
problem; it's an internal dependency within the crate that's breaking Cargo.

It's necessary to run Rust's version of Cargo, not Ubuntu's, when using Rust.
Due to a path problem, I was using Ubuntu's older versions of Rust and Cargo,
but with libraries from the new Rust installation.

[1] [https://users.rust-lang.org/t/crates-io-compatibility-
with-o...](https://users.rust-lang.org/t/crates-io-compatibility-with-old-
cargo/9127/19) [2] [https://github.com/rust-
lang/crates.io/issues/584](https://github.com/rust-lang/crates.io/issues/584)
[3] [https://github.com/rust-lang/cargo/issues/3763](https://github.com/rust-
lang/cargo/issues/3763)

~~~
steveklabnik
Ah yes. This one is indirectly my fault, as I maintain the semver parsing
library, and that included the bug. Sorry about that :(

------
XorNot
What's the Rust IDE story looking like these days? For a language like Rust
(or almost any language really) the best way I've generally found to learn
them is to get a good auto-completing IDE which solves for "what's the
standard library and what can I do?" and let's me focus on getting the syntax
and design methodology right.

Till now Rust hasn't had that. Is there a decent stack?

~~~
allengeorge
IntelliJ with the Rust plugin. Pretty awesome, and always improving.

The maintainers are great, and welcome contributions.

------
0xFFC
I wish they include language service in the stable branch soon.

~~~
StavrosK
You mean the autocompletion server?

~~~
0xFFC
I think they call it officially language service.

~~~
steveklabnik
Yes. It will happen; it was ready to land on nightly just before the branch,
but was held off so that we could have the full, usual, "spends six weeks in
nightly, then beta, then stable" situation rather than almost immediately
jumping into beta. This means it'll hit stable in two releases, 1.19, as long
as nothing goes wrong.

~~~
kibwen
And note that if you're using rustup to manage your toolchain, you can now use
it to install and manage RLS for you as well:
[http://www.jonathanturner.org/2017/04/rls-now-in-
nightly.md....](http://www.jonathanturner.org/2017/04/rls-now-in-
nightly.md.html)

~~~
merb
rustup is really great. First I was a little bit curious if the updates every
6 weeks would ruin my dev environment since I need to update every time. but
rustup makes that a breeze. `rustup update`. that's what to do when there is a
new version, nothing more I don't know that any other compilers/interpreter
that has the same ease of use. except maybe sbt, but that can't self update.
(P.S.: Awesome talk about rust on scaladays:
[https://www.youtube.com/watch?v=C6dNx9pY7p8&index=2&list=PLL...](https://www.youtube.com/watch?v=C6dNx9pY7p8&index=2&list=PLLMLOC3WM2r5Ei2mnSHCD-
ZD04AXovttL))

------
fpgaminer
I still get excited every time there is a new Rust release :D

> When using Cargo’s build scripts, you must set the location of the script in
> your Cargo.toml. However, the vast majority of people wrote build =
> "build.rs", using a build.rs file in the root of their project. This
> convention is now encoded into Cargo, and will be assumed if build.rs
> exists.

This is what I love about Rust's development. Rather than the developers just
using their own ideas about how the Rust ecosystem will use a system, they
instead wait for the ecosystem to come up with its own conventions. Once those
conventions are organically established, they fold them into the official Rust
tools.

It's the equivalent of finding product market fit. More times than not our
ideas about what the market (in this case, Rust users) wants will be wrong.
Better to just adapt to the market.

That's enough praise for now, so ... how about something not so great about
Rust? I started building a password manager in Rust, because I'm not satisfied
with the current options for password managers. This will be my first Rust
project with a GUI and ... so far it's been very painful.

I've looked at GUI in Rust in the past but never tinkered because there were
never any good libraries available. It's now Rust 1.17 and there are still no
good options. For this project I landed on gtk-rs, but it's a nightmare of
Rc's, RefCells, and borrow_mut just to get even the simplest UI working.

I'm not sure yet if this is an issue endemic to gtk-rs, or if Rc's and
RefCells are a necessary evil in Rust whenever GUIs are involved. It's a bit
hard to reason about ownership in this case, where your callbacks can be
called at any time, and if they modify the UI that may trigger another, now
nested callback, which may trigger yet another callback, etc. So it requires a
lot of brain power to think about every borrow and what the lifetime should
be.

Without thinking too much about it, I feel like things could be better. If
Rust was driving the UI loop, and if the callbacks didn't have 'static
lifetimes, then it might be possible shove the UI into an isolated struct and
not have to deal with too many ownership and lifetime issues. But again, I
haven't tried to think it through and it's irrelevant because there's no
mature GUI library in Rust that would allow that.

Of course, none of that reflects on Rust itself, nor on the Rust developers.
This is a third-party issue; it boils down to a lack of good GUI libraries.
That's hardly surprising given how new Rust is.

For now, I'm blundering forward and just hacking together whatever mess of
code works. The critical parts of the password manager are in a separate Rust
library with unit tests, and the password database will have
history/versioning on every entry. So I ultimately don't care if the UI code
is ugly and hacked together. It's just more time consuming than it probably
has to be.

~~~
steveklabnik
You will be happy to hear that there was a GNOME Hackfest in Mexico recently,
attended by several Rust team members. Some productive plans were sketched out
for the future; as the GNOME project adopts Rust more and more, I expect this
to get easier and easier.

You also might like
[https://github.com/antoyo/relm](https://github.com/antoyo/relm)

~~~
fpgaminer
Thank you for the update. Relm looks promising!

By the way, I love that Rust devs stalk HN and read my rants :P

------
cadu2
This thread convinced me that my next language to learn will be Rust (coming
from a C/C++/Python career path).

Can somebody point out a list of resources to start on Rust? Do we already
have a good IDE with proper autocomplete support?

Thank you!

~~~
burntsushi
The canonical source to learn is The Book: [https://doc.rust-
lang.org/book/](https://doc.rust-lang.org/book/)

However, a second edition of the book is in the works and a lot of people have
said good things about it. I think enough of it is filled out to be a good
starting point: [https://doc.rust-lang.org/nightly/book/second-
edition/](https://doc.rust-lang.org/nightly/book/second-edition/)

~~~
cadu2
Thanks! I'll burn my sushi to this!

------
pvg
"If you want to understand Rust replace all occurrences of 'Rust' with 'The
Thing'"

~~~
sqeaky
Was your joke any deeper than a superficial reading of it? I also can't tell
if it was lighthearted or deeply malicious.

~~~
pvg
Unreserved malice and nigh-fathomless depth. I'd say more but I'm in the midst
of designing a language which can precisely and safely express both concepts.

~~~
sqeaky
A shame everyone is downvoting this comment. But you are honest then your
first comment deserves as many downvotes as possible.

Since you are in charge of this new language I won't be using it. The Rust
community has largely figured out how to get work done with minimal malice and
a language that actually exists.

~~~
pvg
In my language, it will be possible to express an impossible number of
downvotes, correcting what is perhaps the most glaring design flaw of Arc.

