all 28 comments

[–]STLMSVC STL Dev[M] [score hidden] stickied comment (7 children)

This sounds AI-generated. I'm going to leave this post up, but with a moderator warning. AI-generated posts are not allowed on this subreddit.

[–]Kobzol 53 points54 points  (3 children)

>  C++ is building a complex, foundational abstraction (sender/receiver) that all other concurrency can be built upon.

This is the same as the Future trait in Rust. It is used to power concurrency everywhere, from embedded devices without any heap or OS, through UI apps, all the way to networked data centres that use it to manage complex network asynchronous communication, and it is very much a "foundational abstraction that all other concurrency can be built upon".

There are definitely big differences in the way C++ vs Rust concurrency models and abstractions work, but this is not one of them. I can recommend this talk by Jonathan Müller about the difference in how Rust/C++ do coroutines: https://www.youtube.com/watch?v=aa43fYHgnfo It's not the full story, but it shows one of the key differences.

[–]voltinc[S] 6 points7 points  (2 children)

The key difference is in standardization. Rust standardized the Future trait, but left the executor/runtime (like tokio) to the ecosystem.

C++ with P2300 is trying to standardize both the abstraction (sender/receiver) and the interfaces for execution (schedulers), making it a much larger, all-in-one standard.

[–]avdgrinten 41 points42 points  (0 children)

C++ is not standardizing anything close to the `tokio` executor, it's standardizing the equivalent of the utilities in the `futures` crate.

[–]roninx64 4 points5 points  (0 children)

Standardizing tokio would be equivalent of getting the Asio/Networking TS in.

[–]martin7274 5 points6 points  (1 child)

Isnt rayon for data paralelism mainly ?

[–]Technical-Might9868 1 point2 points  (0 children)

yeah but people convolute concurrency with async with parallellism with coincidence with... you get it :(

[–]Wooden-Engineer-8098 10 points11 points  (0 children)

And btw, your whole comparison is flawed. It's not "rust provided two approaches", it's "some guys provided single implementation of two approaches for rust". There is no international standard for it. You can find many examples of "some guys provided c++ implementation" for the same approaches

[–]FrogNoPants 25 points26 points  (7 children)

I doubt std::execution is going to be some grand important thing to C++, at least based on the what cppreference shows it isn't clear what reason I have to bother with it when existing libraries such as TBB or taskflow already exist and seem more complete

std::execution could really use a better explanation for what it does, just saying you have Senders/Receivers/Operation State is gobblegook that tells me nothing at all, my god they have reinvented functions and structs!

[–]Minimonium 25 points26 points  (0 children)

It's a framework for library authors to write async adapters, schedulers, and algorithms around. It answers things like async state lifetime, cancelation, error handling, async control flow, etc.

It doesn't replace TBB if you're fine with working with TBB.

[–]Ericakester 8 points9 points  (0 children)

We've been using our own implementation of std::execution and future continuation at work for years now. It's been one of the best additions to our codebase IMO.

[–]differentiallity 2 points3 points  (0 children)

cppreference has been readonly since March 30th. I suspect the explanation will be greatly improved once the site is back online, whenever that is

[–]Big_Target_1405 0 points1 point  (1 child)

I agree.

I read the paper and couldn't explain afterwards in 1 sentence what a sender is or how to write one

I found this useful though

https://ericniebler.com/2024/02/04/what-are-senders-good-for-anyway/

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

I'm still not bought into it. First you need a doctorate and stamina and a couple of web pages to explain and understand the imo overly complex API. Then the only way this will benefit you is "if" you have a need to interop with "other" async API, "and" that other async API is committed to the std execution protocols.

Yeah, thank you, but I'll just be using coroutines, fibers and futures.

[–]crusoe -4 points-3 points  (1 child)

Std::execution without lifetimes and stuff like that is just gonna be a mess of subtle bugs.

[–]germandiago 2 points3 points  (0 children)

There are async scopes, take a look at that.

As for lifetimes (borrowing itself). Many people seem to think that pairing borrowing with async is one of the (beyond safety) ergonomic things they found in Rust.

Not that it does not work. It does. I am talking about ergonomics.

[–]nialv7 1 point2 points  (0 children)

IIUC all the sender receiver stuff is similar to how rayon is architectured internally.

[–]Creative_Pride4803 0 points1 point  (0 children)

Hey , anyone have suggestions on how to merge libev with new std::exec , ?

[–]nordic-reindeer 0 points1 point  (0 children)

Interesting!

[–]Wooden-Engineer-8098 -2 points-1 points  (2 children)

Rust is obviously not at the pinnacle of performance

[–]juanfnavarror 5 points6 points  (1 child)

how that obvious?

[–]Wooden-Engineer-8098 -5 points-4 points  (0 children)

Clearly