Live data from Hacker News

Rust 1.46

blog.rust-lang.org

111–120 of 157 posts

Re: Rust 1.46

#111

Earlier quoted context omitted.

Just let x = &mut bar.0 will work, but this "intelligence" is confined to the body of a single function. Rust possesses the somewhat curious property that there are functions that are intended to always be called like this foo(&bar.x, &bar.y, &bar.z) which cannot be refactored to foo(&bar)

This is a complex topic, but what it boils down to is that the function signature is the API. If you borrow the whole thing, you borrow the whole thing, not disjoint parts of it. This is also why it's okay in the body of a single function; that doesn't impact a boundary. We'll see what happens in the future.

My preferred solution to this is to make partial borrows part of the method definition syntax to make it clear this is part of the external contract of your API. Also I lean towards mimicking the arbitrary self type syntax and land on something along the lines of

  impl Foo {
      fn bar(self: Foo { ref a, mut ref b, .. }) {}
  }
Where that signature tells the borrow checker that those two fields are the only ones being accessed. Nowadays this method would have to be &mut self, which heavily restrict more complex compositions, as mentioned in this thread.

Re: Rust 1.46

#112

Glad to see `Option::zip` stabilized. I tend to write such a helper in many of my projects to collect optional variables together when they're coupled. Really improves the ergonomics doing more railroad-style programming.

Do you have an example? I'm having trouble understanding how zip would be used in practice.

Re: Rust 1.46

#113
post #6

I’m learning rust right now and there is a lot to like. Steady updates like this are also very motivating. The ecosystem feels very sane - especially compared to npm. Top notch Wasm support, cross compiling is a breeze. That said, coming from a FP background (mostly Haskell/JS, now TS) Rust is... hard. I do understand the basic rules of the borrow checker, I do conceptually understand lifetimes, but actually using th…

Ah, if you’re making dsl code or functional combinators, you usually want to ‘move’ your values instead of ‘borrowing’ them.

example:

fn add(mut self) -> Self { self }

fn add(self) -> Self { self }

instead of:

fn add(&mut self) {}

fn add(&self) {}

With this, you will be able to ‘store’ closures easily and apply them later. No more fighting with the borrow checker over where to borrow as mut or not. You will also avoid a few copies.

Re: Rust 1.46

#114

So, I want to learn Rust. I am a C# / Python programmer, experienced. Are there any particular set of problems that I can solve systematically, so that I can learn all the features of Rust?

I am in similar boat. Python centric data scientist. Very tempted to try to learn Rust so I can accelerate certain ETL tasks. Question for Rust experts: On what ETL tasks would you expect Rust to outperform Numpy, Numba, and Cython? What are the characteristics of a workload that sees order-of-magnitude speed ups from switching to Rust?

column-wide map-reduce over large dataframes usually give you a 1000x or so speedup.

With rust you can stream each record and leverage the insane parallelism and async-io libs (rayon, crossbeam, tokio) and a very small memory footprint. sure you have asyncio in python but that’s nowhere near the speed of tokio.

Re: Rust 1.46

#115
post #112

Glad to see `Option::zip` stabilized. I tend to write such a helper in many of my projects to collect optional variables together when they're coupled. Really improves the ergonomics doing more railroad-style programming.

Do you have an example? I'm having trouble understanding how zip would be used in practice.

You sometimes have two Options that must both be Some to have any effect, but other reasons prevent you from making an Option of a tuple of those two fields. Eg think of deserializing a JSON that contains optional username and password strings, but you need both if you are to use them to authenticate to some remote.

In that case, you currently have to write code like:

    if let (Some(username), Some(password)) = (username, password) {
        /* both are set */
    }
    else {
        /* at least one is not set */
    }
With zip this can be written as `if let Some((username, password)) = username.zip(password) {` In this case it doesn't look like a big difference, but it does allow you to chain other Option combinators more easily if you were doing that instead of writing if-let / match. Using combinators is the "railroad-style programming" that kevinastone was talking about. For example, you can more easily write:

    let (username, password) = username.zip(password).ok_or("one or more required parameters is missing")?;
You could of course still do this without .zip(), but it would be clunkier:

    let (username, password) = username.and_then(|username| password.map(|password| (username, password))).ok_or("one or more required parameters is missing")?;
The zip form does lose the information of which of the two original Options was None, so if you do need that information (say the error message needs to specify which parameter is missing) you'd still use the non-zip form with a match.

Re: Rust 1.46

#116
post #112

Earlier quoted context omitted.

Do you have an example? I'm having trouble understanding how zip would be used in practice.

You sometimes have two Options that must both be Some to have any effect, but other reasons prevent you from making an Option of a tuple of those two fields. Eg think of deserializing a JSON that contains optional username and password strings, but you need both if you are to use them to authenticate to some remote. In that case, you currently have to write code like: if let (Some(username), Some(password)) = (userna…

The zip solution however requires any reviewer to look up on what it actually does, whereas the "if let" is more of a language fundamental and known to most reviewers.

Therefore I would actually prefer the long/verbose form without the zip.

Re: Rust 1.46

#117
post #6

I’m learning rust right now and there is a lot to like. Steady updates like this are also very motivating. The ecosystem feels very sane - especially compared to npm. Top notch Wasm support, cross compiling is a breeze. That said, coming from a FP background (mostly Haskell/JS, now TS) Rust is... hard. I do understand the basic rules of the borrow checker, I do conceptually understand lifetimes, but actually using th…

Sometimes you will be annoyed by changes I guarantee it BUT since 1.0 that's decreased a lot and compared to npm it's night and day. You'll think you're dealing with C in relative terms of stability if npm is your baseline :D

Re: Rust 1.46

#118

So, I want to learn Rust. I am a C# / Python programmer, experienced. Are there any particular set of problems that I can solve systematically, so that I can learn all the features of Rust?

I am in similar boat. Python centric data scientist. Very tempted to try to learn Rust so I can accelerate certain ETL tasks. Question for Rust experts: On what ETL tasks would you expect Rust to outperform Numpy, Numba, and Cython? What are the characteristics of a workload that sees order-of-magnitude speed ups from switching to Rust?

Julia might be a better fit for this use case.

That way you leverage a more developed data ecosystem, can call python when necessary and avoid writing low level code.

Depends on the task of course.

Re: Rust 1.46

#119

So, I want to learn Rust. I am a C# / Python programmer, experienced. Are there any particular set of problems that I can solve systematically, so that I can learn all the features of Rust?

https://doc.rust-lang.org/stable/book/ is not purely problems, but does have some problem chapters. (I am a co-author.) https://doc.rust-lang.org/stable/rust-by-example/ is the "by example" introduction, which is all about sample programs, but feels a bit dated, IMHO. Still not incorrect, but not up-to-date. You may also like the O'Reilly book, or Rust In Action, which use more fully-featured example programs more he…

I was super impressed by the O’Reilly book, which throws you right in to writing a multithreaded Mandelbrot set plotter. It also goes through writing a multithreaded HTTP server. Pretty neat!

Re: Rust 1.46

#120
post #47

Earlier quoted context omitted.

Basically, the interpreter interpret's rustc's internal IR, so it can theoretically support the entire language. That's not a good idea for various reasons, though, so its capabilities are effectively on an allowlist, that we expand over time as we're sure we want to enable a given feature.

That seems like a really good design, as opposed to having an AST interpreter like I might do otherwise. But would this indeed support a "much larger set of features" than constexpr as was claimed?

It has been a while, and I’m remembering from a discussion of new features in C++20, but I recall that constexpr isn’t capable of fully supporting memory allocations made during evaluation, while Rust’s const fn will eventually be able to.
Post reply on HN