5 ms·
I do completely agree with your advice of using `Arc`s. But unfortunately, sometimes it gets very tedious to deal with all these `Arc`s: https://github.com/telo
by Hirrolot 4y ago
I do completely agree with your advice of using `Arc`s. But unfortunately, sometimes it gets very tedious to deal with all these `Arc`s: https://github.com/teloxide/teloxide/blob/ec1d41220c51872cf96e597072c63cdfe77c3521/src/dispatching/dispatcher.rs#L418 https://github.com/teloxide/teloxide/blob/ec1d41220c51872cf9....
It also blurs the advantage of Rust as a lifetime validation tool if you use reference counting anyways. But it seems that it's the only viable approach for async at the moment.
- nemothekid 4y agoI have plenty of code like that: let id2 = id.clone(); let watch_id2 = watch_id.clone(); let id3 = id.clone(); let watch_id3 = watch_id.clone(); let ready2 = Arc::downgrade(&ready); let video_stream = async move { // use id2, watch_id2, id3, watch_id3, ready2 } My realization is that in most cases an Arc is the right tool for the job, especially in concurrent applications. I see it as the borrow checker doing it's job, if you have two threads that need to share data and one of them may go away at any moment, the only way you can ensure the memory stays around is with "runtime borrow checking", e.g. a garbage collector. In C++, the way this is solved is usually "just trust me, I won't use this memory here"
- cormacrelf 4y agoThe overall effect of Arcs being more usable is something that was true before Rust. It is an emergent property of Rust too, because it's still true. The alternative to using Arc or similar used to be validating your own lifetimes manually and inevitably making show-stopping mistakes in C/C++. Now the alternative is machine-checking it and being able to never make mistakes. But Arc is still more ergonomic than either. If Rust forces you to use Arc where in C/C++ you would normally just be freewheeling your lifetimes, by complaining about your lifetimes, a lot of people are going to see that as "Rust is really annoying and gets in my way, it's making me choose between a tangle of lifetime bounds and explicit Arcs". The truth is that it is teaching you that your normal style would have led to mistakes and you should never have been coding that way. So people go on complaining about being re-taught until their normal style works in Rust, or until they give up. (I don't think that's what you're doing, this is mainly just to say Arcs are not a waste of the language's power, rather an effect of the language's power to know when your freewheeling would be mere lifetime guesstimation and quite possible buggy in C++.) The author's point is strong though. > the process of designing APIs is affected by numerous arbitrary language limitations like those we have seen so far. There's a long way to go in being able to perfectly express all the ways you might want to use lifetimes. Sometimes you come across a situation when a few of these limitations converge on one spot, and you get the author's problem. But equally, the author is trying to write something that has probably never had its lifetime rules described before. Yes, languages with GCs can do it easily. That was also true of lock-free queues & running destructors. GCs have it easy in a ton of different areas around lifetimes. The core complaint here is that Rust does not have a GC and we have had it really easy being able to rely on one & not having to write down exactly the lifetime bounds that could make it work statically. The author is complaining that there are hundreds of compiler issues preventing some of this being expressed... well, yeah, nobody has ever, EVER, tried to write this stuff down before in a machine-readable way, we are slowly covering the untrodden ground, and you might be in an especially untrodden area. I think that's a pretty good excuse for the compiler having issues and some things being not quite expressible, but it's also an important caveat to "fearless concurrency" and I think the post illustrated that well.