
Announcing Rust 1.20 - steveklabnik
https://blog.rust-lang.org/2017/08/31/Rust-1.20.html
======
kibwen
Interestingly, because Firefox chooses to use stable Rust exclusively, this is
the version of Rust that will be used to deliver Quantum when Firefox 57
releases on November 14 (by which time Rust 1.21 will be out (releasing
October 12), but Firefox 57 will be in beta by September 20).

~~~
smegel
Are there any blogs about how Rust is integrated into Firefox (a mostly C++
program) - i.e. how the Rust runtime is invoked, garbage collection etc?

~~~
mbrubeck
Hi, I'm a Servo developer who worked on some of the Rust code that's in
Firefox. Calls between C++ and Rust code in Firefox all go through "extern C"
functions. Some of the code involves reference-counted smart pointers. We use
RAII wrapper types in both Rust and C++ to ensure that refcounts are
incremented and decremented correctly on either side of the FFI boundary.

P.S. This old blog post is not about Rust-in-Firefox, but it does cover a
related topic: How the Servo browser engine (written in Rust) interacts with
the Spidermonkey JavaScript engine (written in C++ and embedded in both Gecko
and Servo), including garbage-collected JavaScript objects:

[https://research.mozilla.org/2014/08/26/javascript-servos-
on...](https://research.mozilla.org/2014/08/26/javascript-servos-only-garbage-
collector/)

~~~
senatorobama
Are there any engineering openings at Mozilla?

~~~
Insanity
You can check out this page:
[https://careers.mozilla.org/](https://careers.mozilla.org/)

------
SloopJon
In case anyone else runs into this, I was getting this error trying to update
from 1.19:

    
    
        $ rustup update stable
        info: syncing channel updates for 'stable-x86_64-apple-darwin'
        error: missing key: 'url'
    

After I updated rustup from 1.0.0 to 1.6.0 with rustup self update, it worked.

------
jeffdavis
I've been having a little trouble using rust for a little project: I need a
tree with uplinks (meaning there are cycles). I asked on IRC a couple times
and I think what I need is a weak reference inside a refcell, but it's not
very easy to make it work cleanly. For one thing, it doesn't look like refcell
works well with traits (the nodes in the tree are traits, not plain structs).

I'm a bit frustrated because this is so easy in C. Is there any way this can
be easier?

I am imagining a special way to construct cyclical structures where everything
inside would have the same lifetime and be destructed at once. We may need to
hide the references from destructors though, otherwise a destructor could see
a dangling reference.

~~~
msbarnett
> I am imagining a special way to construct cyclical structures where
> everything inside would have the same lifetime and be destructed at once.

The simple way to do that would be to allocate an array, and use indices into
the array rather than pointers/references.

Doing it with pointers isn't so much harder in Rust than C as it is that Rust
is making you deal with _how hard it is to get this right_ , whereas in C the
compiler is happy to let you think it's easy while you accidentally shoot
yourself in the foot.

If you want the Rust compiler to accept your mistakes, you can always wrap it
in an unsafe block ;)

~~~
jeffdavis
But in my example this is not hard to get right in C. The tree is constructed
(on the stack would be fine), then used for a while without mutating it, then
freed all at once.

The thing that makes this hard in rust is destructors. If there's a cycle
between A and B, and you destruct A first, then B, then B's destructor would
see a dangling reference to A. And vice versa if you destruct B first.

But I don't need destructors, or at least ones that can see these references,
so it's frustrating.

~~~
steveklabnik
> But I don't need destructors, or at least ones that can see these
> references, so it's frustrating.

If you bound it so that it only accepts Copy types, then you can know there
are no destructors.

~~~
jeffdavis
Interesting. Then rust should not care about the destruction order, right?

~~~
steveklabnik
For this purpose, no, I don't think. That said I might be missing something
and maybe th compiler doesn't understand this, so I'm not saying it's a
panacea in your case, just might be worth looking at.

------
fdchn2016
Is there a book on Programming Data Structures in Rust. Like from scratch.
Trees, Graphs etc. I would expect the first 2 to 3 chapters to be on Rust
pointer system and the rest of the book to be on implementing Data Structures
using the pointer system.

Similar to like Tanenbaum's book for Data Structures in C or Kruse, Leung and
Tondo's book for Data Structures in C.

~~~
andrewflnr
In Rust, you almost always want to use a library for things like that. If you
want to write the library, you may want the Rustonomicon: [https://doc.rust-
lang.org/nomicon/](https://doc.rust-lang.org/nomicon/). Also, of course, the
"Too Many Lists" article in the other reply. Rust definitely pushes a
different way of thinking about and using data structures.

------
_wmd
What happened to the exhaustive list of unnamed Github contributors? I thought
that was a really powerful marketing method: dear unnamed Github user
x1230134384, your contribution has been acknowledged! Feedback without
requiring identification, it's kindof very cool in a project like this.

~~~
steveklabnik
If you click on the final link to thanks.rust-lang.org, you'll find it there!

There have been talks about moving it back, but it's complicated. You can do
the "duplicate it" strategy, but that has downsides. You could do an iframe,
but then you're using an iframe. You could use JavaScript, but then a whole
different crew of people will Get Mad.

~~~
kbenson
Obviously the solution is to turn the thanks page into an API, add CORS
headers, and then a bit of JS on the announce page to fetch the list from
thanks.rust-lang.org and build the list on load or fall back to the current
behavior.

Good luck determining whether I'm joking or not. I'm not even sure myself...

------
shmerl
Looks like this is moving now: [https://github.com/rust-
lang/rfcs/pull/1615](https://github.com/rust-lang/rfcs/pull/1615) because of
recently added $XDG_BIN_HOME.

------
sevensor
Not a Rust programmer, so the answer to this question may be in TFM -- Rust
has floats, but it doesn't make available constants for inf and NaN? Are you
not guaranteed IEEE754 floats?

    
    
        const NAN: f32 = 0.0f32 / 0.0f32;
        const INFINITY: f32 = 1.0f32 / 0.0f32;
    

Or is that just for the sake of example?

~~~
tatterdemalion
The consts are currently defined in modules with the same name as the type,
`std::f32::NAN;`. This feature allows them to be associated with the type
itself - `f32::NAN`. A small convenience.

~~~
kzrdude
It's more than a small convenience. It's a big feature that we can use when
designing traits and APIs.

~~~
tatterdemalion
Yes of course (I work on Rust). I mean that the difference between f32::NAN
and std::f32::NAN is a small convenience.

------
phkahler
So are these associations (functions and constants) just using the object type
as a name space? Or is there something more to it?

~~~
kibwen
In the most basic sense you can view it like that. When combined with the
typical behavior of traits it gets more interesting. Say you have some data:

    
    
        struct Foo;
    

Then we can make a trait, that defines an interface that we can give to data
later:

    
    
        trait Bar {
            const BAR_CONSTANT: i32;
            fn some_function();
            fn some_method(self);
        }
    

Then we can actually implement that trait for our data:

    
    
        impl Bar for Foo {
            const BAR_CONSTANT: i32 = 42;
            fn some_function() {
                println!("foo's associated function, and the const is {}", Self::BAR_CONSTANT);
            }
            fn some_method(self) {
                println!("foo's method, and the const is still {}", Self::BAR_CONSTANT);
            }
        }
    

Then we can use it like so:

    
    
        Foo::some_function();  // foo's associated function, and the const is 42
        let foo = Foo;
        foo.some_method();  // foo's method, and the const is still 42
    

And now we can take it further. Imagine that you have another piece of data,
`struct Qux`. Then you can do the same and `impl Bar for Qux`. And now you can
write a generic function like so:

    
    
        fn bar_taker<T: Bar>(something_that_impls_bar: T) {
            T::some_function();
            something_that_impls_bar.some_method();
            // And of course we can refer to T::BAR_CONSTANT in here as well.
        }
    

And call it like so:

    
    
        bar_taker(foo);
        bar_taker(qux);
    

AFAIK, the big deal with associated consts is specifically that it allows
generic code like that to refer to different values on a per-type basis.

Here's all this code on the Rust interactive playground if you'd like to poke
at it: [https://play.rust-
lang.org/?gist=60bd64e1b2f52bb91ed0b0cb428...](https://play.rust-
lang.org/?gist=60bd64e1b2f52bb91ed0b0cb428d7303&version=beta)

~~~
phkahler
Thanks for the nice example. I've heard of traits but hadn't read enough to
know what they are. Looks like a form of multiple inheritance. The example you
gave shows polymorphism via traits. That was helpful to me.

------
firebones
May be too late in this thread for a response, but does the completion of the
1.20 release free up some time for the "State of Rust 2017" survey results
blog post before the 1.21 release? I know there was a huge response, and you
don't want to step on the release news, but I'm waiting to see where the user
community stands.

~~~
steveklabnik
It's not really about that; the post is almost done, and you should see it
soon. It was a _lot_ of work to go through.

~~~
chrismorgan
While thinking about such things—what happened to
[https://underhanded.rs/](https://underhanded.rs/)?

~~~
steveklabnik
Results post should be up soonish; I know it's being worked on.

------
pcx
Associated functions and associated constants sound so yum! That's one thing I
would love to have in Flowtype. But classes seem to serve that use case well
enough.

~~~
a_humean
You get something similar to with static methods and properties on class
definitions. In plain ES2017-ish class syntax:

class Test {

    
    
      static value = 1;
    
      static someStaticMethod = () => {
        return 5;
      }
    

}

console.log(Test.value) // 1

console.log(Test.someStaticMethod()) // 5

Edit: Sorry, this actually a Stage 3 TC39 feature. Not sure if you can use it
with flowtype (I think you can), but you might be able to if you enable babel
with stage-3 features:

[https://github.com/tc39/proposal-class-
fields](https://github.com/tc39/proposal-class-fields)

You don't actually need this fancy class syntax anyway. You can just define a
class and then do:

Test.value = 5

Test.someStaticMethod = () => { return 5; }

The class stuff is just sugar over the prototype stuff anyway, and a class is
just a constructor function object with a prototype chain.

~~~
pcx
Yeah, either way it is objects. Traits feel so much more flexible though; and
more natural a layer over JS object-orientedness. It also makes it a pain that
there are some important semantics missing while using classes in JS.
Someitmes Java feels much better.

~~~
akatechis
The real problem is that ES classes map onto a paradigm of prototypal
inheritance rather than traditional inheritance (as in Java). The
discrepancies between the two cause a leaky abstraction, like how a class
still has a prototype chain, for example.

------
xoroshiro
And here I am, still waiting for the second edition of that book on learning
Rust to be finished. I want to learn Rust for fun and I know I should probably
just start on reading the book, but I keep making up excuses not to. I want my
++, --, ?:, SIMD, etc.

~~~
lalaithion
you've got `let x = if y {100} else {99};`, which IMO is more readable than
`let x = y ? 100 : 99`.

------
slavik81
Is f32 the only suffix for float literals? That seems really noisy compared to
just f in C. I'm mostly concerned about vector and matrix declarations, but
even in the examples given, 1.0f32 / 0.0f32 looks like a mess of numbers
compared to 1.f / 0.f;

~~~
kibwen
_> Is f32 the only suffix for float literals?_

Nope. `f32` is for single-precision floats, and `f64` is for double-precision
floats. There have been some people lobbying for `f16` and `f128` as well.

Also, you don't need to use those suffixes. I imagine the OP is using them for
maximum explicitness, but you can just write `1.0` and it will be inferred to
a floating-point type as necessary (contrast `1`, which will be inferred to an
integral type).

~~~
tomjakubowski
GLSL programmers may rejoice in learning that `1.` is accepted syntax too.

~~~
GenKali
Having used Rust since pre-release I'm slightly embarrassed that I'm only
learning about this today.

~~~
ComputerGuru
That's ok. I presume you weren't a C/C++ dev before, that's old school
shorthand for C coders that don't want to type out suffixes or cast numeric
values.

------
kbenson
> An unstable sort could provide this result, but could also give this answer
> too:

It might just be me, but using "this" twice in the same sentence to refer to
two distinct items, one a prior example and one an upcoming example, is
somewhat odd. That said, I understood it perfectly fine, it just caused me to
stop and ponder the wording for a moment. The following might be more clear:

An unstable sort could provide _that_ result, but could also give this answer
too:

~~~
evincarofautumn
In case anyone’s curious, this is called discourse deixis[1]. It’s a frequent
source of errors for non-native English speakers, because in many languages,
you use “that” to refer to an example that follows, but English is unusual in
that it generally uses “this” for the future and “that” for the past.

So that[2] sounds wrong:

    
    
        This[3] probably screwed you up.
    

The somewhat confusing thing is that “this” is _also_ used for the present or
recent past, especially in more formal writing.

[1]:
[https://en.wikipedia.org/wiki/Deixis#Discourse](https://en.wikipedia.org/wiki/Deixis#Discourse)

[2]: The following example

[3]: The previous sentence

~~~
JoshTriplett
> English is unusual in that it generally uses “this” for the future and
> “that” for the past.

I don't know that I'd describe it as "future" and "past"; it's more that
English uses "this" for "current" and "that" for "other", whether past or
future.

For instance, "this situation is broken, that solution looks promising" uses
"this" to refer to the present and "that" for the future.

~~~
evincarofautumn
I was referring to past/future _in the text_. Deixis is about how words and
phrases like “this”, “that”, “here”, &c. are contextualised. Your example is
unrelated to discourse deixis because it’s not referring to a piece of the
surrounding discourse. We use different forms of deixis and spatial metaphors
for time, like “the end is near” or “the past is behind us”—in some languages,
the past is _in front of_ you (mnemonic: you can see it) while the future is
behind (you can’t).

~~~
JoshTriplett
Ah, fair enough; I hadn't interpreted your previous comment as
backwards/forwards in the text. Thanks for the clarification.

------
copx
"Associated functions" = class methods

"Associated constants" = limited version of class variables

Rust keeps approaching C++'s feature set..

I am amazed that the above wasn't in Rust to begin with, though. Can't think
of any other languages which has classes but no class methods/variables.

~~~
steveklabnik
I, at least, don't really think of Rust as having classes. Rusty design
patterns don't really look like many traditional OOP design patterns. This is
often a hurdle for new Rust programmers. Chapter 17 of the book
([https://doc.rust-lang.org/book/second-
edition/ch17-00-oop.ht...](https://doc.rust-lang.org/book/second-
edition/ch17-00-oop.html)) is trying to grapple with this question.

Part of the difficulty here is nailing down what "class" even means, exactly.
Rust doesn't fit into either of the three major schools of OOP, which I
personally nickname the "smalltalk school", the "java school", or the
"javascript school".

~~~
zaphar
Obviously Rust is in the 4'th school which I like to call "The Rust School".

All kidding aside, I think for any regular working day programmer Rust is
obviously OOP. The debates are really just which parts of which favorite
school of OOP you think Rust is inspired by.

But what really matters is that Rust gives you:

* Encapsulation

* Polymorphism.

* And Code Reuse.

Which are the only three things anyone who reaches for OOP is really looking
for anyway. As fun as the PL theory discussions are. (Kind of a Hobby for me
at least) I think those are the bits that actually matter to the people who
truly need an answer to the question "Is Rust OOP or not?"

~~~
kibwen
I agree that it's better to focus on encapsulation/polymorphism/reuse, but the
reason why I personally object to the idea that "for any regular working day
programmer Rust is obviously OOP" is because inheritance is usually taught
above all of these as the fundamental property of OOP.

I doubt I'm the only one whose high school and college exposure to OOP was to
model "Dog is-a Mammal, Cow is-a Mammal, Mammal is-a Animal", and if a
newcomer to Rust tries to do the same as their "hello world" then they're
going to be greatly frustrated. Again, this isn't to say that the phrase "Rust
is OOP" is necessarily incorrect, only that it's going to backfire if we going
around shouting it, due to misaligned expectations.

~~~
zaphar
Is-A does not and should not imply Inheritance. It merely implies
polymorphism. I didn't get formally trained so I can't comment on what
college/high school's teach but if they teach that Is-A relationships imply
Inheritance then claiming Rust is OOP seems like a good way to educate the
mis-educated regarding the difference.

~~~
leshow
What kind of polymorphism? Traditional OOP is subtype polymorphism. You can't
really do that in Rust. It's main polymorphism is parametric and ad-hoc
polymorphism a la Haskell. If that's considered OOP then OOP is so broad it's
not a useful term

~~~
pjmlp
What is traditional OOP?

The Simula, Smalltalk, Lisp, SELF or BETA model?

Yes, OOP is broad, just like FP also is.

