Live data from Hacker News

Common Rust Lifetime Misconceptions (2020)

github.com

51–60 of 89 posts

Re: Common Rust Lifetime Misconceptions (2020)

#51
post #24

Earlier quoted context omitted.

I think there's a lot to be gained by not writing Rust like C, to the extent that it might be worth taking some time to pick up another language (maybe a lisp variant?) first. 2.) Be careful because &String is not &str, although in many cases you can pretend thanks to magic of AsRef/AsDeref. 4.) If you find yourself calling is_none, rethink things a bit. Pattern matching and the various destructuring (e.g. if let) fe…

> maybe a lisp variant? Nah, go with an ML-family language. Maybe even Standard ML, because it will nudge you away from writing "C in ML" and encourage you to pick up the idiomatic way of doing things. (Laurence Paulson's book has an online version available for free on his homepage).

SML is great, but I always suggest OCaml. Still my favourite language that I never get to write these days!

Re: Common Rust Lifetime Misconceptions (2020)

#53

Once I discovered ‘static was the subtype of all lifetimes rather than the super things began clicking for me.

`static is actually the superlifetime of all lifetimes, but & is contravariant in its lifetime parameter (and covariant in its type parameter).

This is not true anymore: https://github.com/rust-lang/rust/pull/107339

Re: Common Rust Lifetime Misconceptions (2020)

#54

Earlier quoted context omitted.

`static is actually the superlifetime of all lifetimes, but & is contravariant in its lifetime parameter (and covariant in its type parameter).

Mind expanding on this? The nomicon describes &’a T where both ‘a’ and ‘T’ are covariant. I thought I had a clear picture but now I’m confused. https://doc.rust-lang.org/nomicon/subtyping.html#variance

`rustc` used to use different terminology than the nomicom, but this is no longer the case: https://github.com/rust-lang/rust/pull/107339

Re: Common Rust Lifetime Misconceptions (2020)

#56

Earlier quoted context omitted.

IMO stringy data is a good example of where you should think about what you're returning in part because common APIs (e.g. regex) will take a more nuanced approach. If you're creating a new string, then sure return String. But if you have a path where you could just return the original input, consider returning a Cow .

burntsushi actually regrets making regex replace return a Cow : https://github.com/rust-lang/regex/issues/676#issuecomment-6... . I’m glad it does, and wish it took an impl Into > there, for the reasons discussed in the issue, but burntsushi has a lot more experience of the practical outcomes of this. Just something more to think about.

So from reading those comments, I'd come to the opposite conclusion: Cow is absolutely the right choice and perhaps String should really have been Cow.

Insofar as taking an impl into, burntsushi linked to a rust playground demonstrating where that approach falls down. In general (heh) taking arguments , especially options or stringy ones, that are generalized over an into impl is one of those things that seems real nice at first but gets real unpleasant pretty quick IMO.

Re: Common Rust Lifetime Misconceptions (2020)

#57

I just clone everywhere and write Rust like a high level language. Then, once I need to optimize more, if I ever do (as Rust is many times faster than other languages even with liberal cloning), then I simply go through and remove the clone where needed.

Me too. I also do this with .unwrap() - when I'm pretty sure of the happy path - while I'm prototyping. It's pretty easy afterwards to run back through and replace .unwrap() calls with better error handling. But as I improve, I'm getting more in the habit of using matching directly. Understanding lifetimes is probably really helpful for understanding library errors though and I need to go deeper there for sure

This is what I love about Rust, and other languages with these kinds of constructs. You have to acknowledge that something might e.g. fail. You can choose to do "nothing" (e.g. unwrap), but it must be done explicitly, which makes the ignored cases simple to identify later

Re: Common Rust Lifetime Misconceptions (2020)

#58
post #51
post #24

Earlier quoted context omitted.

> maybe a lisp variant? Nah, go with an ML-family language. Maybe even Standard ML, because it will nudge you away from writing "C in ML" and encourage you to pick up the idiomatic way of doing things. (Laurence Paulson's book has an online version available for free on his homepage).

SML is great, but I always suggest OCaml. Still my favourite language that I never get to write these days!

For practical programming I'd probably agree, but if the point is to learn a non-Algol way of thinking then I think SML is a better way to go; OCaml makes it easier to write imperative-style code, for better and for worse.

Re: Common Rust Lifetime Misconceptions (2020)

#59

Earlier quoted context omitted.

Good advice, though I'd recommend Rc > instead of Arc > if you're not sharing the data between threads, to avoid synchronization overhead. I use Arc pretty rarely.

The overhead of an uncontested lock is not much more than a memory operation but it allows you to be able to use the same code in threaded context in tokio async which is a huge benefit. Unless you need the optimization (i.e. you profiled and determined that Arc in a hot loop is slowing you down) I think it's fine to use Arc in general.

> The overhead of an uncontested lock is not much more than a memory operation

An atomic memory operation! These can be orders of magnitude slower than regular memory operations.

Re: Common Rust Lifetime Misconceptions (2020)

#60

I just clone everywhere and write Rust like a high level language. Then, once I need to optimize more, if I ever do (as Rust is many times faster than other languages even with liberal cloning), then I simply go through and remove the clone where needed.

> as Rust is many times faster than other languages even with liberal cloning

Have you really compared? I have. Rust was faster for "small input", but quickly got beaten by Java and other languages I tried because the cost of doing things this way grows exponentially. I suggest you run benchmarks before you make your mind up and start throwing opinions around.

Post reply on HN