Settings

Theme

Rust 1.49.0

blog.rust-lang.org

241 points by pietroalbini 5 years ago · 116 comments

Reader

nitsky 5 years ago

I am surprised the blog post doesn't mention the stabilization of binding both by-move and by-ref in patterns [1]. I have personally been waiting on this one for several years. Time to go remove my workarounds. Thanks!

[1]: https://github.com/rust-lang/rust/pull/76119

  • steveklabnik 5 years ago

    There is always an art to what to decide to put in vs not, and it wasn't 100% clear to us how important folks consider this feature. We waffled a bit, it was basically a coinflip on putting it in or not.

    • the_mitsuhiko 5 years ago

      I generally started going from the blog posts to the changelog as I felt for a few times now that the stuff I care about was not in the announcement blog post.

      • steveklabnik 5 years ago

        Yeah, it's just impossible to please everyone, especially in releases like these, which have a few minor things and that's it. Rust 1.51 will be easy, given that "const generics" is a huge headline feature almost every Rust user will care about, but for features that are full of tiny things, it's just way way less clear.

        This has the funny effect of posts getting harder to write as time goes on; we have less releases with big, important features, and more releases with "tons of bugfixes and some minor improvements."

        • Kinrany 5 years ago

          Do you have any ideas for changing the format, to make it easier to write about these things in a way that lets people read the parts they want?

          Possibly write about the reasons something was changed and the use cases improved, instead of the changes themselves?

          • steveklabnik 5 years ago

            I don't, because I think it is fundamentally impossible. I'm willing to be proven wrong though!

            I do try to write about the reasons why and use-cases improved. One of the issues is that that increases the amount of text, which directly goes against the idea of quickly finding what you want.

            At the end of the day, if you want to know everything, you have to read everything. There's no shortcuts. I try to highlight the best things that the most people will want to know about, but if you really want to know everything, there's no better way than going straight to the source, like I do to create the post in the first place.

            • kzrdude 5 years ago

              You don't want to sign Lin Clark for doing helping write these? If we could dream :)

              I was imagining something spatial, a drawing, a map, something that makes it possible to overview and place the new features in context with each other. Probably nothing that can be realized.

        • lumost 5 years ago

          It might be worth separating the different improvement areas by section to let people zoom in on what they care about.

          • steveklabnik 5 years ago

            We already do that in a pretty granular way, between language, library, compiler, and toolchain features, unless I'm misunderstanding you.

            Regardless, I don't think the cost/benefit is right here; the posts and notes are already pretty short, and should only take a few minutes to read, even if you read all of them.

            • lumost 5 years ago

              aye - the note is very short, I meant that given an index at the beginning one could have more detailed sections that highlight the changes for each section of the language to help avoid "can't please everyone" at the risk of "pleasing no one".

ufo 5 years ago

A question for the Rust crowd, from someone who's thinking about giving Rust another chance in 2021:

Last time I tried getting into Rust, some years ago, the recommended way to install it was to use the rustup tool. You were also kind of expected to learn using the "nightly" version of the language, because much of the documentation and stackoverflow answers depended on that.

Is this still the case now that we're about to enter 2021? Is it OK to learn rust by installing it via "apt install", or is it still recommended to use rustup? Is it OK to stick just to stable Rust or should I expect that I will need to install the nightly version at some point?

  • ReactiveJelly 5 years ago

    I used Rust pretty regularly through 2020 at work and home, all with stable Rust.

    All the stuff I did worked fine - 3D graphics with OpenGL and SDL2, web services with Hyper and Tokio (recently hit 1.0!), and CLI apps.

    If you want to try apt install first, you can do that - It's easy to remove. But personally I do use rustup.

  • the_duke 5 years ago

    rustup is still the recommended way to install.

    Rust has a 6 week release cadence, and while the language has settled down significantly over the last 1-2 years, there are still a lot of new features arriving that library maintainers are eager to use. Combined with performance improvements, you will almost always want to use a recent compiler.

    Relatively slow moving package repositories are not a great fit for that reason. Rustup also handles installing support for various architectures - which are often not packaged well - and fast-moving tools like rust-analyzer.

    The nightly situation has gotten much, much better though. Almost non of the popular crates still require nightly, and staying on stable is just fine for most projects.

    • steveklabnik 5 years ago

      (It's six weeks not three months)

    • majewsky 5 years ago

      > Relatively slow moving package repositories are not a great fit for that reason

      Not every distribution is Debian Stable.

      • ithkuil 5 years ago

        It seems that ubuntu 20.10 groovy gorilla is stuck at 1.43

        As a library maintainer I need to make the choice of which version to target.

        It's easy to accidently use features of a recent rust version, as you can see in this example:

        https://github.com/mkmik/slyce/issues/17

        I could work around this issue and pin the rustc version in the CI system to avoid regressions, but is it worth the effort since it's likely that this particular user will eventually depend on another library that uses a feature of >1.43 and thus eventually give in and use rustup? I want to be helpful towards users of my library, but I wonder if the most rational choice is to encourage users to upgrade the toolchain more liberally.

      • pthariensflame 5 years ago

        Yes, but some of them are, and some are even worse.

  • danhor 5 years ago

    I haven't needed nightly much this year, except for an unstable platform (avr) not supported in stable. It has gotten much better and I feel there are very few reasons you might use nightly. Since often the packaged versions of the toolchain in distros are out of date and many crates take advantage of the newest features, I'd heavily recommend it.

  • Scuds 5 years ago

    even the rust-analyzer plugin for plugin for VSCode installs and runs without any fuss, definite improvement from when I last saw it in 2019.

    Re: apt install - I never trust the OS packages for anything like developer tools, I'd rather have everything run out of my home directory. Then again, I'm not a C/C++ developer where the OS, libraries, build tools are all intertwined.

  • steveklabnik 5 years ago

    Regarding nightly:

    https://blog.rust-lang.org/2020/12/16/rust-survey-2020.html

    > the number of users who are relying on a nightly compiler at least part of the time continues to drop - down to 28% compared with last year’s 30.5% with only 8.7% of respondents saying they use nightly exclusively. When asked why people are using nightly the largest reason was to use the Rocket web framework which has announced it will work on the stable version of Rust in its next release. The next largest reason for nightly was const generics, but with a minimal version of const generics reaching stable, we should see less of a reliance on nightly for this feature.

    TL;DR: unless you're doing certain specific things, stable Rust should work well for you.

    Regarding rustup vs apt, you can absolutely install via apt if you want to. Depending on what version you get, you may or may not be far enough behind the rest of the world for it to be a pain. Which version you'll get depends on the specifics of the distro.

    • pjmlp 5 years ago

      Basically nightlies are just like the "preview" features in Java, .NET and C++ ecosystems, or import from future in Python.

  • ragnese 5 years ago

    I've been using Rust since 2016 and I've never installed a nightly version for code I was writing. (I did install nightly for some code completion tool or something back in the day. Maybe Racer?)

    I think it's still recommended to use rustup.

  • rapsey 5 years ago

    Stable rust is perfectly fine. The vast majority of Rust users are on stable only.

    • nobleach 5 years ago

      Unless you want to try out Rocket. That one STILL requires nightly...

      • ibraheemdev 5 years ago

        Rocket 0.5 (which is coming soon) will compile on stable. Alternatively, you can the master git branch directly. Very few libraries still require nightly. Most of them have moved or are moving to stable.

Galanwe 5 years ago

Any chance to see increased support for 8bit AVR in upcoming releases?

I know Rust is community driven, so it's not like contributions will appear from thin air. But I guess maybe it would be time to promote/incentivize people to contribute support for microcontrollers. This is a realm where C reigns and Rust would be a bowl of fresh air.

  • dbrgn 5 years ago

    32 bit microcontrollers are well-supported, and often cheaper, more power efficient and with more features than old 8-bit uCs.

    https://github.com/rust-embedded/wg

    • sitkack 5 years ago

      That is true but there are literally millions of AVR based Arduinos out in the world and I can confirm that they are totally usable with Rust.

    • Galanwe 5 years ago

      Maybe, but 8bit MCUs are simple, efficient, have a huge community & resources, and more importantly exist in convenient DIP & SOIC form factors.

  • lights0123 5 years ago

    Rust has full support for AVR, excluding function pointers due to current LLVM bugs. Building on stable would be nice though, as it currently requires a custom target JSON file.

    • Galanwe 5 years ago

      > Rust has full support for AVR

      Last time I checked (6 month ago), the Rust AVR fork had just been merged upstream. This removed the necessity to build a forked rustc from a patched llvm.

      I would have to re-check recent updates, but at the time there were still a lot of bugs, no core libs, etc.

      That's not what I would call "full support".

  • steveklabnik 5 years ago

    Folks are still working on it, yep.

    I mean, Rust does have support for many microcontrollers. I do ARM stuff for work, for example. Just not AVR. It'll be nice to have it though!

pjmlp 5 years ago

Congratulations to everyone.

For me it was specially nice to have some minutes shaved off from full builds.

dbrgn 5 years ago

Rust, where even unstable functions can be stable!

(Yes, I know that "unstable" in slice::select_nth_unstable refers to unstable sorting.)

darksaints 5 years ago

Curious why the distinction between tier 1 and tier 2 targets is testing. Is testing that burdensome? Why can't the tests be run on them?

  • steveklabnik 5 years ago

    The difference is not "testing" in a broad sense, the difference is "tests guaranteed to pass" vs "tests may run if they exist but we don't gate on them passing."

    Being able to guarantee that they pass means having the expertise to fix any issues, and with a timeliness to be able to fix them and not block a release. That requires people around to support the target, with a higher burden than tier 2.

    (Technically, it's even more than "not block a release" it's "not block any PR that may start failing on that target," since all tests must pass before a PR is landed.)

  • Diggsey 5 years ago

    Commits don't reach master until they have passed all the test suites. As such, it is very burdensome to add more test suites: it increases the time taken to run the test suite and reduces the throughput of all rust development. Not to mention, many of the tier 2 or lower targets are not easy to run in CI.

    You could ask: why aren't the tier 2 tests just run before release? But then, if they are broken it may be a significant amount of work to fix, and could delay the release.

    Maybe there is a middle-ground where tier 2 tests are run daily, but then you need a team of people just to fix those tests, because it will no longer be on the original PR author to make sure those tests pass before their PR is merged.

  • nikic 5 years ago

    An important factor here is hardware access. Tier 2 targets just produce cross-compilation artifacts, tier 1 targets require actual hardware to run on. For example, a tier 1 macos aarch64 target is impossible until the hardware can be run in CI, for every merge.

  • koenigdavidmj 5 years ago

    Tier2 compiler can be built with a cross-compiler, perhaps, but you don’t have consistent access to hardware to run the tests on. Just a guess

  • kzrdude 5 years ago

    CI is expensive, even more on those targets.

  • afavour 5 years ago

    I think it’s that the tests aren’t run, and consequently, they don’t guarantee the tests pass, which means it might not behave exactly the same as a tier 1 platform. So the difference is bigger than just tests.

mindv0rtex 5 years ago

I really enjoy using Rust for personal side projects. It made me a better C++ developer. I'm excited about stabilized const generics to be able to speed up my linear algebra code.

This issue though prevents me from recommending Rust for closed source development to my colleagues: https://github.com/rust-lang/rust/issues/40552

Dowwie 5 years ago

A lot of people are using Rust for advent of code 2020. It's really interesting to see the role that AOC is having with adoption and leveling up Rust knowledge.

candied_scarf 5 years ago

i am disappoint there isnt mention of more private/reproducible release binary output from compilation

https://github.com/rust-lang/rust/issues/40552

https://github.com/rust-lang/rust/issues/75263

  • steveklabnik 5 years ago

    This bugs are still open, so there’s no reason to talk about them in a release announcement. If they were fixed, and made it into a release, then there’d be more to talk about.

option_greek 5 years ago

I wish they would streamline the string handling capabilities. Currently the conversions between String and &str are really ugly to look at. In general the conversion between types don't seem all that great with developers having to either use crates or write their own code. They need to take more inspiration from C# which continues to be the benchmark of elegance (obviously personal opinion). That said, rust is still better than C++ - namely its package management is great. I just wish the compiler doesn't keep second guessing me :D

  • steveklabnik 5 years ago

    > the conversions between String and &str are really ugly to look at.

    This is entirely up to you; unless you find method calls ugly, in which case, you've got bigger problems :)

    > They need to take more inspiration from C#

    Could you elaborate a bit? I'm not familiar with what C# does here.

    • alpaca128 5 years ago

      What I tend to stumble over is how String and &str each have some methods and features that the other lacks, e.g. concatenation. Which of course makes sense with basic understanding of string slices, but sometimes I can't shake the weird feeling that I'm cloning some String unnecessarily.

      And I just wish generic type parameters wouldn't have to be propagated through all types touching them.

      That said I'm really happy with how it develops and Rust comes with many little details that I sorely miss in other languages. Thanks for all the effort.

      • gamegoblin 5 years ago

        The methods on `String` should be a strict superset of the methods on `str` because `String` dereferences to `str`, thus `String` gets all of the `str` methods for free.

        If you're familiar with say, `Vec<u8>` and `[u8]`, `String` and `str` are basically the same except they are contractually valid UTF bytes. So just like you can `push` and `extend` to a `Vec`, you can do the same to a `String`.

        With regard to generic type parameters, if you want to code in Java or Go style, you can use dynamic dispatch trait objects to remove type parameters.

        • brundolf 5 years ago

          > The methods on `String` should be a strict superset of the methods on `str` because `String` dereferences to `str`

          I've found that sometimes this doesn't happen automatically (at least when passing as an argument; maybe not when calling methods). i.e., you have to explicitly call .as_str() in some situations. Even as someone who's comfortable with the String/&str distinction and moderately familiar with Rust, it's not clear to me where this is and isn't necessary. The compiler just tells me when I make the wrong guess.

          • aldanor 5 years ago

            Maybe read a bit on Deref: https://doc.rust-lang.org/std/ops/trait.Deref.html

            Any time you have a &String reference, it triggers coercion to &str.

            • Measter 5 years ago

              Unfortunately that is not always the case. This fails to compile, for example (and is fairly irritating):

                  let my_str = "Hello".to_owned();
                  match &my_str {
                      "Hello" => (),
                      _ => ()
                  }
              • glandium 5 years ago

                try &*my_str

                • Measter 5 years ago

                  Yes, that's the trivial "fix" to make it work, but that's not my point. In most other similar situations the compiler does that for me, but not here. It feels like something the compiler should be doing, not me.

    • option_greek 5 years ago

      In C# there is a helper class: https://docs.microsoft.com/en-us/dotnet/api/system.convert?v...

      I'm still figuring my way around rust so obviously some noob questions follow: -> what's with the move/copy mess ? I know why they are needed but it seem to be in the face with all the explicit '&' all over the place in any reasonably sized code. Why not hide it a bit by letting the implicit copy to happen to simpler structures ? (at compile time).

      -> Why no love for inheritance? :) - it makes certain patterns easier to implement

      -> Why no love for global/static variables ? I know they are prone to be misused but some patterns like singleton really need a lot of shortcuts to implement. And there will always be some cases where you want to keep variables with static and global scope

      • the_duke 5 years ago

        You are essentially complaining that Rust is not C#, while at the same time admitting that you don't know much about the language.

        Rust is much lower level and makes very different tradeoffs. Sometimes for the sake of performance, sometimes to enhance code readability.

        But most of the design decisions are there for a reason, and are good choices.

        Simple types (that are small and can be trivially memcopied) can implement the `Copy` trait, which makes cloning transparent. For other types, the `Clone` trait is there with `.clone()`. Having expensive copies be explicit is a intentional design decision.

        For value conversions, the `Into/From` and `TryInto/TryFrom` traits make conversions a (usually type inferred) function call (.into(), .try_into()), which is really quite convenient, though at the expense of readability.

        Regarding strings: they are are definitely complicated and sometimes awkward in Rust. But I'd argue that strings are inherently complicated. Most languages hide this complexity by just allocating and doing everything on the heap, which is not great in a language that values performance and wants to support environments without allocators.

        • johnsoft 5 years ago

          Expanding a bit on conversions: C#'s `Convert` conflates several different operations.

          Examples:

          Convert.ToInt32(String) – This is _parsing_. In Rust, use `parse`.

          Convert.ToString(Int32) – This is _stringifying_. In Rust, use `to_string`.

          Convert.ToInt64(Int32) – This is an _infallible conversion_. In Rust, use `into`.

          Convert.ToInt32(Int64) – This is a _fallible conversion_. In Rust, use `try_into`.

          In all these cases, Rust gives you more immediate semantic information about the conversion, and in fewer characters too!

      • umanwizard 5 years ago

        > Why not hide it a bit by letting the implicit copy to happen to simpler structures.

        This is already the case. Built-in types that are simple enough to be copied implicitly already are (roughly: those which don't manage any memory or other resources), and you can enable this for your own types with `#[derive(Copy)]`, as long as they are composed only of implicitly copyable types.

            #[derive(Copy)]
            struct S {
                x: i32,
                y: usize,
                z: Option<Result<(), ()>>,
            }
        
            fn f(x: S) {
                // ...
            }
        
            fn main() {
                let s = S { x: 0, y: 0, z: Some(Ok(())) };
                f(s);
                f(s);
            }
        
        
        Something like `String` isn't implicitly copyable in Rust, because it manages memory, and therefore copying it would require a heap allocation.

        The Rust way of forcing non-trivial clones to be explicit is much better than C++ IMO, where someone forgetting a `&` or an `std::move` somewhere can cause an innocuous-looking function call to be arbitrarily slow.

        In C# there are not implicit copies either (except of value types), because more complex types in C# are accessed via pointers to garbage-collected heap objects. Rust doesn't have a garbage collector, though.

        • brundolf 5 years ago

          The misunderstanding may come down to the fact that strings are "primitives" in many languages - for usability reasons - despite carrying the memory/performance traits of a full, heap-allocated "object". If someone has never worked in a language where strings are not primitives, I can see how they might be irked/confused by suddenly having to deal with that.

      • hctaw 5 years ago

        > Why no love for global/static variables? I know they are prone to be misused

        Rust doesn't deal with "prone to misuse" but "provably safe, else explicitly unsafe, or made safe by the programmer through wrapping code." Global variables are inherently unsafe and need to be wrapped as such.

        Of course you'll need global state at some point in your life. What Rust does is yell to remind you that it isn't thread safe.

        If you stop thinking about a Rust program as a script where the runtime figures the hard stuff out for you, then these design decisions make a lot more sense. You have a lot more knobs to twiddle than in C#, no garbage collector, and no runtime. The compiler is pretty smart, but it tells you the things it knows and you're responsible for working around the limitations to create sound programs that the compiler can optimize.

      • steveklabnik 5 years ago

        Rust has From/Into and TryFrom/TryInto that do the same thing, as far as I can tell. It's not clear to me what the differences are, maybe someone else in this thread will know. :)

        > Why not hide it a bit by letting the implicit copy to happen to simpler structures ?

        This is the Copy trait.

        > Why no love for inheritance

        There are a variety of reasons, but one interesting one is that inheritance and strong type inference have issues, and we have very strong type inference. Beyond that, there are various other reasons, but what it really comes down to is that there's just not a ton of pressure to actually implement it; it's not enough of an impediment for Rust users to justify adding it. Most requests come from people who do not write Rust, and once people get into Rust and how it works, they don't seem to need it much anymore.

        This is of course very general and there are some people who love it and want it badly anyway, but "some people exist who want this feature" is not enough to make it happen. Rust already has a lot of features, and some people say too many. We have to be careful here.

        > Why no love for global/static variables ?

        What does "love" mean? Rust absolutely supports these.

        • option_greek 5 years ago

          Sorry for got to mention the 'mutable' part. So a mutable singleton variable that has to be marked with an unsafe keyword (and forces the functions that use to be marked as unsafe). The other day I was struggling to implement a singleton (for loading large data from disk) and finally decided to just pass it down the whole chain from the main method. May be I'm missing some easy pz way of doing this ?

          • steveklabnik 5 years ago

            So yes, that is because it is unsafe, according to Rust's definition of safety. However, there are tools you can use to remove this.

            First of all, I find that many people aren't using multiple threads, and therefore, what they want is a thread-local, not a static. For that, you can use https://doc.rust-lang.org/stable/std/macro.thread_local.html

            If you do need a static, then there are libraries like https://docs.rs/lazy_static/1.4.0/lazy_static/ and https://crates.io/crates/once_cell to help too. We have talked about adding something like this to the standard library, but it hasn't landed yet. https://github.com/rust-lang/rust/issues/74465 is the tracking issue for when it does. The reason that we don't have this yet is that it is not super urgent, given that the libraries already exist.

            Now, both of those give you immutable statics, but that's where interior mutability comes in. As you can see from the thread_local examples, you can use a RefCell there, and if your type is simple enough, maybe even regular Cell. For lazy_static or once_cell, you may want to use Mutex<T>, or RwLock<T>, or some other type. For simple integers, the various Atomic* types might be better, for example. The reason this isn't built in is exactly because there are so many options; people need all of these specifics, so we have to provide them, so there's no single built-in thing.

          • brundolf 5 years ago

            Here's how you can do global mutable state in Rust:

              #[macro_use]
              extern crate lazy_static;
            
              use std::sync::Mutex;
            
              lazy_static! {
                static ref ARRAY: Mutex<Vec<u8>> = Mutex::new(vec![]);
              }
            
              fn do_a_call() {
                ARRAY.lock().unwrap().push(1);
              }
            
              fn main() {
                do_a_call();
                do_a_call();
                do_a_call();
            
                println!("called {}", ARRAY.lock().unwrap().len());
              }
            
            I agree that this isn't the most ergonomic, but like most unergonomic things in Rust, there are reasons for it being so.
            • steveklabnik 5 years ago

              (You'd probably replace the first two lines with "use lazy_static::lazy_static;" in today's Rust, that older style isn't as idiomatic.)

          • shepmaster 5 years ago
      • adkadskhj 5 years ago

        > 'm still figuring my way around rust so obviously some noob questions follow: -> what's with the move/copy mess ? I know why they are needed but it seem to be in the face with all the explicit '&' all over the place in any reasonably sized code. Why not hide it a bit by letting the implicit copy to happen to simpler structures ? (at compile time).

        So there's a lot to unpack here, but implicit copies do happen - if it's a copy-able data structure. Strings are huge, so no implicit copy. As far as `&` being too much to identify references vs not, i'm not sure how it could be made any shorter to identify a reference. You're already, commonly, hiding the lifetime associated with that, so it's really `&'a str`, but Rust lets you drop the `'a` most of the time.

        Considerable effort has been put into easing the language and lowering syntax. What's left is essentials imo. I _want_ to see when something is a reference. I _want_ to know generic types. etcetc.

        > -> Why no love for inheritance? :) - it makes certain patterns easier to implement

        I can't speak much here. I've been using Go and Rust for so long i've forgotten what classical inheritance is actually useful for haha. The Go/Rust pattern of Structs, shared behavior, etc cover all use cases for me. i don't find myself missing something, fwiw, but i can't speak to which is "best".

        > -> Why no love for global/static variables ? I know they are prone to be misused but some patterns like singleton really need a lot of shortcuts to implement. And there will always be some cases where you want to keep variables with static and global scope

        You can have global variables fwiw. Granted, i use `lazy_static` which simplifies it a bit, but there's nothing i'm aware of which prevents this pattern. I've typically just used it in tests though. Globals are the devils candy ;)

      • brundolf 5 years ago

        If you just prefer the "helper" style of calling, Rust allows methods to be called either way:

          let foo1: String = "bar".into();
          let foo2 = core::convert::Into::into::<String>("bar");
  • ChrisSD 5 years ago

    I'm not sure what you mean by conversion between String and &str? To get an owned String from a &str you just use the `into` method, no?

    • steveklabnik 5 years ago

      Strings implement a lot of different conversions, since they're very general. You've got:

      * Into, with s.into()

      * An inherent method, .as_str()

      * Deref coercion, &s

      * Reborrowing, &*s (this builds on Deref too but isn't a coercion and can be done in places where coercion doesn't kick in)

      ... and probably some others I'm forgetting.

      • ChrisSD 5 years ago

        Right but as a general rule you'll mostly only be using `s.into()` to get a `String` from an `&str`. Or `&s` to deref `String` to a `&str`. I'm not sure why this would require a crate to handle?

        The other ways are more "advanced", for when you're dealing with (for example) potentially unsafe coercions or you don't want to rely on inference for some reason.

        • steveklabnik 5 years ago

          I agree with you that I'm not sure what your parent is talking about, I'm just here to give all the examples. Deref coercion takes 99% of my String -> &str conversions, and I reborrow for that rare 1%, personally.

      • option_greek 5 years ago

        -> specifically this one: "Reborrowing, &*s"

        Would have been easier to implement with a copy constructor I guess. Why not implicitly clone in some cases (since classes like String gets used so frequently).

        • steveklabnik 5 years ago

          Well, Rust doesn't have constructors, let alone copy constructors. Clone goes from &T -> T, so that is the exact opposite conversion needed here, let alone auto-clone.

          Automatically copying strings may not be a great idea: https://news.ycombinator.com/item?id=8704318

        • shadow31 5 years ago

          > Why not implicitly clone in some cases (since classes like String gets used so frequently)

          Because they get used so frequently. Why would we want to add expensive clones to frequently used operations?

          This would be like asking why LINQ methods in C# aren't deferred by default. Yes, there's a few situations where that would be nice but it would make the functions largely useless because of how poor performance would be.

apta_ 5 years ago

What IDE do people use for rust nowadays?

  • UtherII 5 years ago

    The IDE support use to be very poor but nowadays there are two really nice contenders :

    - Jetbrains IDE with the Rust plugin (maintained by Jetbrains itself). The free IntelliJ IDE Community works really well. CLion or IntelliJ Ultimate are necessary for debugging support

    - The Rust-analyser tool. A language server that can be used, in theory, on any IDE supporting the LSP protocol. Code is the most used IDE with this tool since it is the reference IDE of the project.

  • ibraheemdev 5 years ago

    VS Code is one of the more popular ones, although it doesn't really qualify as an IDE. IntelliJ is probably the most popular IDE for Rust development.

  • k5z 5 years ago

    Always Vim

deccanchargers 5 years ago

Nice.

Rust is nice language btw.

But,when will stable version of Rust be released? By stable,i mean, number of new features added must not be too much. Rust currently seem to be adding too many features every release (which is nice but also not so good at same time)

  • steveklabnik 5 years ago

    > By stable,i mean, number of new features added must not be too much

    What is "too much"? How many would you prefer? How does this release have too many features? This release has three, and they're all pretty small. Some could even argue that they may not even count as new features, but remove restrictions between combinations of existing features.

  • dbrgn 5 years ago

    By that measure, both Java and JavaScript are highly unstable programming languages.

  • johnsoft 5 years ago

    By this logic, languages are never "stable" until after they die

  • MetaDark 5 years ago

    It sounds like your definition of stable applies to a very limited set of programming languages. The only thing I can think of that would fit that definition is C.

    Have you seen how many new features have been added to C++20? (which is probably the closest language to Rust) Not to mention any of the dynamically typed languages.

    • 1_player 5 years ago

      Elixir is stable in that sense as well. Which IMO is very nice as I don't feel I have to relearn the language if I leave for 2 years, and I have to rewrite a 2 years old project to make use of any new idiom and syntax sugar.

  • jcelerier 5 years ago

    > but also not so good at same time

    why ? do they charge you by the feature ?

boxmonster 5 years ago

I recently wrote a utility for myself in Rust after having done several in C#. I like both languages, but Rust introduces pain points for no apparent reason. For example, I hate this way of dealing with errors

    match result {
        Ok(value) => value,
        Err(result) => { 
            panic!("error traversing directories {}", result);
        }
    };
It's awkward and ugly. I'm back to C#, now on .NET 5.) and find that it just got noticeably faster! It was already fast.

"Astonishing Performance of .NET 5: More Data"

https://medium.com/swlh/astonishing-performance-of-net-5-mor...

  • steveklabnik 5 years ago

    This code is equivalent to

        result.unwrap_or_else(|e| panic!("error traversing directories {}", e));
    
    There are a lot of methods on various types to reduce this kind of thing. If you didn't want to interpolate the value of e, it would be even simpler:

        result.expect("error traversing directories");
    • shepmaster 5 years ago

      > If you didn't want to interpolate the value of e

      For those reading along (not Steve) expect does do that, but using the Debug formatter instead of Display, as the grandparent used.

    • boxmonster 5 years ago

      the unwrap_or_else makes a lot more sense, because I could just use the ? operator, but if I don't want to panic, then I'll use unwrap_or_else. I am not by any means an advanced Rust programmer and in fact learning from your book, so I didn't mean to offend anyone. My initial impression of the match syntax for return values was that I didn't like it. Sorry.

      • adkadskhj 5 years ago

        Match has it's place in unpacking common Enum types like Option and Result, but typically you'll reach for functional patterns like `Result::map`, `Result::expect`, `Result::unwrap_or`, and of course `?` as they're able to do the same thing but in far less code.

        I think the downvotes are because both the example and the generalized statement that C# is "noticeably faster" is bait / lazy.

        • nobleach 5 years ago

          The railway error-handling paradigm is superior (in my mind) to the common try/catch/throw pattern in many other languages. It promotes errors to first class citizens. It's a monadic pattern that many functional programmers like to employ.

        • boxmonster 5 years ago

          Definitely not bait because I like to jump around with languages so it's natural for me to compare them (that's why I do it.) I wrote my web server in Go, my util to find duplicate directories in Rust, etc.. I wasn't saying C# is faster than Rust, I said C# got faster.

          • adkadskhj 5 years ago

            > I wasn't saying C# is faster than Rust, I said C# got faster.

            Ah gotcha - my mistake :)

      • steveklabnik 5 years ago

        It's all good!

  • j1elo 5 years ago

    "I recently wrote a utility for myself in ASM after having done several in C. I like both languages, but ASM introduces pain points for no apparent reason."

    IMO the_duke summarized it perfectly in other comment: You are essentially complaining that Rust is not C#; Rust is much lower level and makes very different tradeoffs; most of the design decisions are there for a reason, and are good choices (https://news.ycombinator.com/item?id=25593825)

    People considering Rust as an alternative for higher-level programming languages are in for a potential surprise or two. I guess this happens because Rust has received a lot of attention and promotion, enough to make some people consider it, where otherwise they wouldn't have thought of using tools that stand at a lower level than what is most appropriate for their needs (or knowledge).

    EDIT: I've now read that in this particular case, the parent commenter is consciously playing with different languages to learn about them. Still, I think it would be a misconception to think that C# and Rust are at an equivalent level of programming abstraction, and thus should offer similar ergonomics.

    • ragnese 5 years ago

      It's funny. Rust is a strange beast. It's a low level language. But, in some specific ways, it's more expressive than a lot of popular high level languages: traits are sometimes nicer than interfaces, strong concurrency guarantees are great compared to the nightmare of parallel processing in e.g., Java, discriminated unions with pretty good pattern matching is missing from many popular high level languages.

      You still have languages that can't (really) even do async/threaded computation (Python, PHP, JavaScript/Node can't do threads AFAIK).

      I've said this before: "Rust is the highest level low level language I've ever used. Java is the lowest level high level language I've ever used."

    • boxmonster 5 years ago

      HN won't let me edit my comment to clarify (after 2 hours?) but I was pleasantly surprised that Rust felt like C# to me and I didn't have to struggle much because I already know about references, pointers, stacks and heaps (from C and asm) Dictionaries and Lists were easy to work with. I grokked the borrow checker. I was motivated to make my post because I struggle with the various return types and syntax like

          enum Result<T, E> {
             Ok(T),
             Err(E),
          }
      
          match header.get(0) {
              None => Err("invalid header length"),
              Some(&1) => Ok(Version::Version1),
              Some(&2) => Ok(Version::Version2),
              Some(_) => Err("invalid version"),
          }
      
      I wasn't saying it was bad, just a pain point for me.
  • __henil 5 years ago

    Now try learning about Go's error handling, you will feel better about it :) /s

    Jokes aside there are many helper methods on `Result` to make it more Rustic, try looking into: https://doc.rust-lang.org/std/result/enum.Result.html

  • rapsey 5 years ago

    This is pretty nonsensical code so kind of hard to see what your point is.

    • steveklabnik 5 years ago

      If the value were being assigned to a variable, it would make tons of sense, IMHO. That it's not means that it's a little useless, but I'm guessing this was typed up for this example, not copy/pasted from real code.

Keyboard Shortcuts

j
Next item
k
Previous item
o / Enter
Open selected item
?
Show this help
Esc
Close modal / clear selection