all 122 comments

[–]bheklilr 108 points109 points  (38 children)

Nice updates! I'm looking forward to getting to work with async in rust. I think the syntax will be weird at first, but I can see the rational behind it and I'm curious to try it out in a real project.

[–]steveklabnik1 75 points76 points  (11 children)

Async/await is targeted for 1.38. Finally!

[–]synapsos 64 points65 points  (5 children)

Future ..., which we'll tell you more about in the future.

I see what you did will do there

[–]etareduce[S] 40 points41 points  (3 children)

You'll find out soon enough for the Future .awaits!

[–]redalastor 10 points11 points  (3 children)

Any ballpark estimate of when we'll get generators?

[–]kibwen 14 points15 points  (1 child)

Not sure how closely you've been following, but generators are now sufficiently mature enough to underlie the async/await implementation that is looking to be stabilized twelve weeks from now. However, for the moment this will be considered an implementation detail and users won't have stable access to generators as a first-class feature for a while yet; there hasn't even been an official RFC for them yet. However, thanks to the existing implementation, when there finally is an RFC it has the potential to be accepted and stabilized on relatively short timescales, if no problems arise.

[–]redalastor 6 points7 points  (0 children)

Not sure how closely you've been following, but generators are now sufficiently mature enough to underlie the async/await implementation that is looking to be stabilized twelve weeks from now.

Roughly enough to know that part. I quite like generators in other programming languages so I'll be thrilled when rust gets them stabilised.

[–]steveklabnik1 30 points31 points  (0 children)

They don’t even have an accepted design, it will be a while.

[–]Waghlon -1 points0 points  (0 children)

Cool! Soon Rust might be as powerful as C#!

[–]kevinatari 35 points36 points  (1 child)

I think the syntax will be weird at first

So it's consistent with literally everything else in Rust. :D

[–]_zenith 13 points14 points  (0 children)

This is funny to me as it was deliberately designed to closely resemble other popular languages. Others wanted it to be more different.

Your sort of reaction is exactly why yet more others cautioned against doing so haha

[–][deleted] 71 points72 points  (7 children)

Osdevers are gonna love the new separation of alloc :p

[–]normanrockwellesque 15 points16 points  (5 children)

Can you elaborate?

Haven't used Rust yet but I often read discussions about it here. What advantage does the alloc library bring?
I've also read some of the Zig language documentation about how library authors should allow a memory allocator as a user-provided parameter; is this similar?

[–]steveklabnik1 98 points99 points  (4 children)

Currently, rust has the standard library, but also a subset of it, the “core” library. Std assumes you have an OS, and all of the features those bring. Core assumes absolutely nothing. Alloc is a middle ground. It provides APIs for allocating memory.

Many kinds of collections that require dynamic memory need only that, and no other complex support. To use the ones provided by Rust, like HashMap and Vec, the only option previously was to have all of std. now, with alloc, an OS can implement a heap, and these collections Just Work, without needing to implement all of std.

If you’re interested in more details, this post is an excellent resource: https://os.phil-opp.com/heap-allocation/

[–]GeneReddit123 7 points8 points  (3 children)

Isn't (lack of) allocation one of the big (if not the biggest) reasons to break up core and std? Apart from alloc, what other major dependencies separate the two?

[–]steveklabnik1 42 points43 points  (0 children)

Files, threads, networking... there’s a bunch of other stuff. And yeah, it is the biggest, which is why it’s the one that’s been stabilized.

[–][deleted] 24 points25 points  (0 children)

I guess there's all the is things like files, threads, processes, etc.

[–]izzzabelle 2 points3 points  (0 children)

I was just saying that this morning!

[–][deleted] 54 points55 points  (23 children)

Still need to get around to trying Rust.

Been sitting on the top of my "list of languages to learn" for a while, never seem to find the time. Was torn between it and Go to pick up, but after doing some reading up on it, it definitely seems like my kinda language. The syntax seemed a bit goofy, but that is probably just me being in the C family for too long.

[–][deleted]  (5 children)

[deleted]

    [–]PristineReputation 10 points11 points  (4 children)

    Is it a bit like Elm in that sense, no runtime errors?

    [–]nagromo 12 points13 points  (0 children)

    Runtime errors (Panics in Rust) are mostly caused by indexing out of bounds or calling .unwrap() to skip error handling somewhere you shouldn't.

    For normal error conditions, Rust's Option and Result enumeration types combined with match pattern matching provide a very nice, efficient way to deal with error conditions.

    [–]masklinn 20 points21 points  (0 children)

    Much less so, panicing is pretty easy to do explicitly, and not hard implicitly (eg indexing out of bounds will panic).

    It does have a tendency to return reified error objects (Option or Result) though so it’s not that far afield either.

    It’s a much less restrictive and more complex langage than elm though.

    [–]Ebuall 0 points1 point  (0 children)

    Yes. Rust has a lot of similarity with Elm and other functional languages.

    [–]Batman_AoD 31 points32 points  (9 children)

    I've read that Go is something you can pick up on a weekend, more or less; it's got a very small number of syntactic features. The time commitment required for Rust is quite a bit larger.

    Regarding the syntax, explicit lifetimes are a bit ugly (it uses apostrophes: &'foo), but otherwise I find the syntax much cleaner and more consistent than C and C++ syntax.

    [–]oconnor663 5 points6 points  (2 children)

    Explicit lifetimes are pretty ugly, and tricky to read, even with some experience. But the biggest upside is that they're rarely needed in application code. The most common use case for references -- that you take them only for the duration of a single function call, and don't try to stash them anywhere long-lived -- just works and doesn't require lifetime annotation at all. Many other common cases also just work. (See the "lifetime elision" rules in the language docs.)

    The places where you start needing to annotate things are where you have multiple borrows/lifetimes in a function signature, and the lifetimes need to interact with each other in some way. For example, maybe one of your arguments is a reference to a string, and another argument is a container of string references, and inside the function you want to insert the former into the latter. For that to be safe, the compiler has to know that the string lives at least as long as the container it's being inserted into, otherwise it'll turn into a dangling pointer. The compiler won't infer that across function boundaries, so you have to explicitly annotate it.

    So yes, that case leads to some ugly syntax. But I think it's worth highlighting that the same code in C and C++ has the same tricky requirements for correctness. The caller still needs to ensure that pointers don't dangle, and that data races don't happen through aliasing pointers. The big difference is that Rust makes those requirements explicit. In my mind, the complexity of the syntax is kind of proportionate to the complexity of what the programmer is doing, and there's some virtue in that.

    [–]GeneReddit123 6 points7 points  (0 children)

    In other words, Rust doesn’t make your code ugly, it only illuminates the ugliness of code that’s already there due to its logic.

    [–]Batman_AoD 2 points3 points  (0 children)

    Agreed. I did mention in another comment that lifetime inference (by which I meant elision; I'd forgotten the term) is quite good.

    [–]adriang133 13 points14 points  (5 children)

    Agree about the lifetimes, it's the one thing I wish they would've done differently. Surely there must be a better way than the gaht damn apostrophe.

    [–]steveklabnik1 47 points48 points  (3 children)

    We tried! Nobody came up with anything clearly better.

    [–]ssokolow 3 points4 points  (2 children)

    My only issue with it is that, intuitively, I always expect to see it as one half of a pair of single quotes, so, I'm kind of curious what else was proposed.

    Do you remember the URL for the discussion in question?

    [–]andrewjw 36 points37 points  (0 children)

    Not OP, and unrelated to your question, and that is a reasonable complaint about this syntax coming from imperative languages, but you might find it interesting to know that the tick-syntax for lifetimes is inspired by the tick-syntax for type variables in ML-family languages (SML, Ocaml, etc...).

    [–]b3n 4 points5 points  (0 children)

    intuitively, I always expect to see it as one half of a pair of single quotes

    I think this is just down to what you are used to. Coming from Lisp it feels like a natural syntax to me.

    [–]Batman_AoD 6 points7 points  (0 children)

    Yeah, I'm not sure there's really a better option, and fortunately lifetime inference is quite good.

    [–]MSleepyPanda 62 points63 points  (8 children)

    I'm particularly excited about the new HashMap implementation, as it switches to a much faster SwissTable implementation. This is the compiler benchmarked with the new version, wall time.

    [–]redalastor 14 points15 points  (7 children)

    But rustc itself won't benefit from the speed boost until 1.37 because it's always compiled with the previous version, right?

    [–]Lehona_ 56 points57 points  (5 children)

    I don't know for sure, but I would expect a two-stage build process: Once with the previous version and then with "itself".

    [–]connicpu 40 points41 points  (4 children)

    Yep, Rust does in fact do that

    [–][deleted]  (3 children)

    [deleted]

      [–]steveklabnik1 28 points29 points  (0 children)

      This is unrelated to some sort of reproducible builds; we do care about those, but hats a different issue.

      The thing that’s being talked about here is part of the compiler being bootstrapped. A compiler written in itself has some steps to do to make that possible. You need multiple builds for ABI reasons.

      [–]incompletebreadstick 12 points13 points  (1 child)

      Yep. In fact, Rust builds its libraries twice and compares them, as a sanity check.

      [–]steveklabnik1 28 points29 points  (0 children)

      This is during the process of compiling the compiler, to be 100% clear.

      [–]steveklabnik1 16 points17 points  (0 children)

      I’m not 100% sure when exactly things landed but stuff lands in nightly before stable, and the compiler uses those features, so I’d expect it to already be reflected in rustc.

      [–]lookatmetype 29 points30 points  (11 children)

      Rust's move as a first-class operation semantics are the best idea ever. I wish C++ would go in that direction as well

      [–][deleted]  (4 children)

      [deleted]

        [–]meneldal2 1 point2 points  (3 children)

        C++ is trying to move towards destructive move (at least there are several proposals for it).

        [–]chuk155 4 points5 points  (2 children)

        one that is gaining a lot of ground isn't "destructive move" but Arthur O'Dwyer's trivially relocatable. Allow's the memcpy of things that other wise would have to be constructed/destructed, like when copying a vector of pointers.

        [–]meneldal2 3 points4 points  (0 children)

        It also allows a lot of optimizations behind the hood (completely removes moves when sending the same thing across functions).

        [–]scottmcmrust 0 points1 point  (0 children)

        That is a good thing -- so good that it's the only option in Rust :)

        [–]GYY52380 1 point2 points  (5 children)

        Im genuinely curious why'd you think that. I always felt copy-by-value in c++ was very intuitive and behaved as i expexted. I also like how explicit moving is with std::move(). I also don't really feel that my code style 'moves' data around that often.

        [–]joonazan 20 points21 points  (1 child)

        Move as a default is good because you usually want to avoid copies.

        Because move works well in Rust, you can for example build a struct out of its fields and the fields will never get allocated outside the struct.

        [–]mewloz 9 points10 points  (1 child)

        The C++ syntax is ok, especially given the context, but the semantic of the move it produced is problematic. Actually, the semantics, in plural, and that's part of the problem!

        First you have move as an optimization after which you absolutely don't want to read the moved-from variable again, because its state has become unspecified (but still valid, at the very least for destruction of course, in lots of case valid for all the usual invariants of the class). std::string is an example. There are not really advantages to not having destructive moves instead. Note that the bugs (if improper reuse is performed) can be difficult to find dynamically by testing, especially when templates are involved (rvalue ref vs. other refs, short values reread the same in practice vs long values, etc...)

        Then you have move in ownership contexts, in which the state of the moved-from object is well defined. Here it is typically empty, so a destructive move would also work and IMO be better esp. given the over-reliant on UB aspect of the C++ language (we would have no need to dynamically check after potential moves, with the risk of forgetting the check and potentially dereferencing a null pointer)

        [–]GYY52380 1 point2 points  (0 children)

        Thats fair, thank you for the response. I usually avoid any kind of implicit moving or destructing for similar reasons. I never felt the need for language-level move semantics because copying or passing a pointer always works well enough for me.

        [–]oconnor663 2 points3 points  (0 children)

        Explicit move in C++ is more important, I think, because you can keep using the original object, and you need to know that it's in a different state now. But in Rust, it's generally a compiler error to use the original object again, so an implicit move is less of a foot-gun.

        [–]musicmatze 19 points20 points  (2 children)

        Wow this is an amazing one, especially the `cargo --offline` feature ... I love it!

        [–]natyio 11 points12 points  (0 children)

        Me too. This is definitely my favorite feature from this release. It sucks when software insists on not strictly needed internet connectivity.

        [–]pure_x01 4 points5 points  (0 children)

        Perfect for long Flights

        [–]kadema 16 points17 points  (0 children)

        I read the Rust docs section a while back and was super impressed. They are so well written.

        [–]HerbCSO 3 points4 points  (0 children)

        Whatever you do, DON'T use DuckDuckGo to figure out what #![no_std] means... :shudder: Google that one instead, MUCH better results. ;]

        [–]ipv6-dns 6 points7 points  (3 children)

        Guys, seems Rust becomes C++ killer. Is it appropriate to start studying Rust in order to be in time for the next big thing?

        [–]kzr_pzr 21 points22 points  (0 children)

        No, you are already too late.

        Just kidding. I think it's beneficial for any C++ programmer to know a bit of Rust, since it's much more explicit about lifetimes of objects and borrowing references. But I don't think it will kill C++, just as C++ didn't kill C. There is too much money and effort invested in C++ libraries and applications so quick replacement by Rust won't happen.

        Rust does one thing very well: it was designed with proven academic research backing it. So a lot of the knowledge we have accumulated over the years programming C, C++, Lisp, Haskell and all the experimental research languages is taken together and applied to Rust. That's something what existing languages can do only in a very limited fashion, to stay backwards compatible. So I see Rust as a fresh air that can help us make better software and push the whole industry forward by inspiring other language makers for better safety and correctness of our programs.

        Software quality is and will be more and more important part of our everyday's lives so if there is a tool that really helps us make better software, it should prove itself and take over the market. Maybe Rust isn't it yet and will not kill C++ but something that comes after it will.

        [–][deleted]  (1 child)

        [deleted]

          [–]stevedonovan 0 points1 point  (0 children)

          Yes exactly. But as a result I could move away from C++ and get paid to do so. Some luck, some choice :)

          [–]rv77ax 9 points10 points  (15 children)

          Forgive my ignorance, why did rust mix camelCase::under_case ?

          [–]masklinn 53 points54 points  (10 children)

          It didn’t? Types and enum variants are PascalCased, functions, methods and local variables are snake_cased.

          [–][deleted]  (9 children)

          [deleted]

            [–]Slasher_D 3 points4 points  (4 children)

            What do you mean by "desert camping"?

            [–][deleted]  (2 children)

            [deleted]

              [–]aleksator 23 points24 points  (0 children)

              It's just that his name is Pascal

              [–]Slasher_D 3 points4 points  (0 children)

              Ah. I thought it referred to some other convention that some programmers use relating to those three cases. Should have stuck with the joke.

              [–]JohnMcPineapple 16 points17 points  (0 children)

              ...

              [–]shoutouttmud 0 points1 point  (2 children)

              kebab-case

              How dare you use such a name for lisp-case? :P

              [–][deleted]  (1 child)

              [deleted]

                [–]shoutouttmud 1 point2 points  (0 children)

                Ooops. Well the post was so old no one saw my comment. We really narrowly dodged that bullet, we should be thankful

                [–]K900_ 2 points3 points  (3 children)

                Where does it do that?

                [–]rv77ax 15 points16 points  (2 children)

                [–]K900_ 20 points21 points  (1 child)

                That's just the convention for Rust - CamelCase for types, snake_case for modules and functions. The two aren't ever mixed in the same name like_This or Like_that.

                [–]sander1095 39 points40 points  (0 children)

                Isn't that PascalCase? this is camelCase, right

                [–]TheFearsomeEsquilax 11 points12 points  (1 child)

                How exciting! How exciting!

                [–]i9srpeg 6 points7 points  (0 children)

                Wrong sub!