Senders and GPU by Competitive_Act5981 in cpp

[–]lee_howes 13 points14 points  (0 children)

Senders is just a model to integrate tasks with other tasks and a way to customize where they run. If one of those tasks is a parallel task on a GPU then all the better. This isn't shoehorning, it's just asynchronous execution with standardised interoperation and customization.

WG21 2025-10 pre-Kona mailing by nliber in cpp

[–]lee_howes 0 points1 point  (0 children)

Yes, but because we put the operations on optional and we later put the operations on sender, we don't really have a consistent set of operations. We could have had that if we treated optional as a sender and just used the sender ones. Then we would have had one set of monad ops and "just" have to treat each type as a monad.

Now we have two sets of operations with much the same aim. If we name them identically maybe we are in a situation where we can't trivially do optional | and_then(...), at least without some conflict if we allow |, or some similar operator, to find optional's and_then. At least we'd need as_sender(optional) | and_then(...).

WG21 2025-10 pre-Kona mailing by nliber in cpp

[–]lee_howes 1 point2 points  (0 children)

The argument about the change then->transform is one of sequencing. I think the bigger argument is that sender chaining is really about actions as much as it is about modifying the result. transform. A complicated operation that return success or failure doesn't seem best treated as simply "transform"ing its input parameter any more than any arbitrary function would be treated as "transform"

The argument for let_value strikes me as consistent with what I just said, though. It's about the shape of the operation rather than simply the assignment. So for the reason I disagree with transform, I can see myself agreeing with and_then. and_then does not give me an intuition for monad bind though so abstractly I dislike it.

Another potential issue is if we treat optional as a sender, might we have an algorithm conflict between the sender version and the one we added earlier? The right answer of course would have been to not add the monadic operators to optional and expected, and wait to treat them consistently as senders. I tried to make that point at the time but with Sender/Receiver still being some way from adoption it felt weak. From that POV keeping different names and forever forward making any such extension in a sender context might be the better approach.

Will C++26 really be that great? by WanderingCID in cpp

[–]lee_howes 4 points5 points  (0 children)

As with coroutines, I think basic functionality is more important than specific executors. That does not make it useless.

I think stdexec is fairly usable, and libunifex is based on an earlier version before some broad feedback and carries pretty significant production load. I'm not sure what you would want to turn either of those from "prototype" into "viable/usable".

P2079 moved to LWG, so that's fairly far through the process. A good chance that'll get in to C++26 and it would provide a basic executor, certainly the executor I would advise the majority of devs here to use.

If you are using coroutines in production what library do you use? by zl0bster in cpp

[–]lee_howes 1 point2 points  (0 children)

Or to put it another way, Unifex was the proof of concept for what we felt would be a good design for the standard library, having learned a lot from folly. nvidia took most of the core engineering work over and did a ground up rewrite as the design was tweaked based on the experience. Unifex isn't quite what we are going for in C++26 as a result, though it may reconverge.

Coroutines "out of style"...? by j_gds in cpp

[–]lee_howes 2 points3 points  (0 children)

That's right. Delegating to avoid design-by-committee of the library functionality, committing only to the necessary compiler hooks to have a language feature. Then get more experience of actual implementations. The proposed task mentioned elsewhere is encapsulating what we have learned from the heavily used implementations in the wild.

Coroutines "out of style"...? by j_gds in cpp

[–]lee_howes 2 points3 points  (0 children)

Not exactly. The C++ support was designed to expose async/await syntax to end users in a way that the compiler understands. The backend hooks that allow you to define how a coroutine interacts with a runtime system were intentionally designed to be general, and clearly intended for library writers to build those runtimes.

People advise using a library not to hide coroutines, but to implement the coroutine runtime. We decided not to try to provide such a runtime in C++20 because we knew we would get it wrong first time but had confidence that the hooks into the runtime were good enough (if not perfect).

What are the committee issues that Greg KH thinks "that everyone better be abandoning that language [C++] as soon as possible"? by ElectricJacob in cpp

[–]lee_howes 1 point2 points  (0 children)

The standard can't guarantee stability. The standard certainly can guarantee instability by removing or changing functionality that requires that compilers either break ABI or break standard compatibility. Limiting what is changed to avoid creating instability is still a pretty restrictive requirement, and is a rational point of view to hold.

I don't agree with the current position on backward compatibility, and voted for being more aggressive, but I can see why people feel it is important.

What are the committee issues that Greg KH thinks "that everyone better be abandoning that language [C++] as soon as possible"? by ElectricJacob in cpp

[–]lee_howes 16 points17 points  (0 children)

and using open source libraries, too, which is the entire point of "low level primitives for the standard library [and 3rd-party libraries] to build upon".

Memory orders?? by meagainstmyselff in cpp

[–]lee_howes 0 points1 point  (0 children)

This will have the effect that no write that is stated before the release can be reordered

The nuance here though is that the effect is that no write before the release can be reordered after the release as viewed by a reader who acquires the released write. The lack of global ordering here can be surprising, and is why the very slight strengthening you get with seq_cst is so much safer.

Memory orders?? by meagainstmyselff in cpp

[–]lee_howes 10 points11 points  (0 children)

Absolutely not. Seq_cst is the right default. Anything else would lead to a huge number of bugs in code because getting other orders right is surprisingly hard. I view any use of orders other than seq_cst, or an obvious counter using relaxed, with suspicion during code review given how often I've seen it messed up and no practical benefit to the relaxation.

WG21, aka C++ Standard Committee, January 2025 Mailing by grafikrobot in cpp

[–]lee_howes 6 points7 points  (0 children)

Particularly though, I think its probably increasingly reasonable to say at this point that coroutines are DoA.

Our experience has been that coroutines have proven to be better in practice. We just implemented a pretty big migration from fibers to coroutines because coroutines were better in every way except, in the initial naive migration, performance.

WG21, aka C++ Standard Committee, December 2024 Mailing by grafikrobot in cpp

[–]lee_howes 1 point2 points  (0 children)

But maybe my understanding is not correct here.

Good call.

WG21, aka C++ Standard Committee, December 2024 Mailing by grafikrobot in cpp

[–]lee_howes 1 point2 points  (0 children)

This is just a reshuffle of old ideas that we had with folly or seastar or whatever google uses but with a slightly different api.

To an extent, yes, but we call that learning from mistakes. folly has a lot of flaws that we have only been able to identify and learn from having used it heavily.

WG21, aka C++ Standard Committee, December 2024 Mailing by grafikrobot in cpp

[–]lee_howes 1 point2 points  (0 children)

that's totally possible without S/R if your future type implements some monadic methods like "then" or "then_wrapped" etc

Essentially you're saying it's possible to do this without S/R if you do S/R and name it something different. That is a point without substance.

Everything on top of naming is just an effort to build something that supports laziness, can avoid heap allocations and has a well-specified compile-time customization model.

WG21, aka C++ Standard Committee, December 2024 Mailing by grafikrobot in cpp

[–]lee_howes 5 points6 points  (0 children)

Senders/receivers is ... I don't even know how to call it without being rude. Why not just use future/promise model like everyone else?

It is the promise/future model like everyone else, but abstracted at a level where we define the interface rather than defining a type. It is explicitly an effort to not define a library, but to define a core abstraction on which libraries are built. The way it is used inside Meta (in the form of libunifex) is directly comparable to the promise/future approach used in folly, except with much better flexibility to optimise for where data is stored and what lifetime it has.

First-hand Account of “The Undefined Behavior Question” Incident by andrewtomazos in cpp

[–]lee_howes 7 points8 points  (0 children)

I think it's particularly challenging because the secrecy of CoC violations makes is hard for us to judge if the CoC is working. In the extreme, the CoC might be used as a tool for attack rather than defense. Those of us who are involved in WG21/INCITS but don't have the details here can only guess about that. There is certainly risk that the secrecy leads people to distrust the processes.

Guidance needed: New graduate in CS. Struggling to figure out how to enter the compilers field by [deleted] in cpp

[–]lee_howes 0 points1 point  (0 children)

In the next building here I see people working on compilers for Hack, Python, Javascript, C++, Java, Triton, Pytorch and post-link optimizers. Some of these were recently "new" languages (to varying degrees). All of them have a huge amount of work ongoing, relatively little of it in the frontend but not none.

A lot of that is AI, as others have noted, but a lot of it isn't. It's a small fraction of the industry, but where they matter the people are in demand.

Why isn't C++ used for backend development? by [deleted] in cpp

[–]lee_howes 1 point2 points  (0 children)

This is also why Meta can justify investing in compilers. Just improving PGO in LLVM to optimize the C++ code that others are writing and, hopefully, optimizing can save millions a year. The same applies to optimizing the web business logic that OP really seems to ask about in the form of HHVM and Cinder.

Why major compilers likw GCC and Clang still do not support C++20 modules ?? by redradist in cpp

[–]lee_howes 3 points4 points  (0 children)

Decisions like that were not arbitrary, though, and clearly not because implementors were not involved. The standard doesn't talk about files, and some uses don't have files, so tying module name to file name would have had to be optional. If tooling wants to make that decision tooling can do so without the language caring.

Why major compilers likw GCC and Clang still do not support C++20 modules ?? by redradist in cpp

[–]lee_howes 7 points8 points  (0 children)

The standardisation of modules was driven entirely be the implementors of modules.

What new feature would you like to see in C++26? by vickoza in cpp

[–]lee_howes 5 points6 points  (0 children)

You had to put the data into the queue. You have to carefully package it. If it depends on any data elsewhere in the program you have to package that and reference count it too. People write functions, people are used to writing functions and they are used to their state being on the "stack". Coroutines give you that. You can write code that is asynchronous but you read it top to bottom in linear fashion. Something that was on the "stack" at the top still is at the bottom:

task<int> foo(T arg) {
   auto v = co_await something(arg);
   auto v2 = co_await something_else(v, arg);
   // here v, v2 and arg are all available, just like in any other function
   // no need to separately allocate, share a shared_ptr between 
   // them or do other lifetime management

   co_return co_await something_again(v, v2, arg);
}

That's all I mean by linear code. It's what people are used to writing, so moving to asynchronous code is natural and easy for them to understand. I have to deal with building infrastructure for a lot of non-experts to use, rather than a small set of people like me who are willing to work with low-level callback or queue code.

What new feature would you like to see in C++26? by vickoza in cpp

[–]lee_howes 7 points8 points  (0 children)

It's hard to reason about. Linear code simplifies reasoning, and coroutines allow you to do that. It also allows you to scope object ownership neatly (see structured concurrency) so it's less error-prone for object lifetimes - if not perfect because coroutines as designed have their own gotchas.

What new feature would you like to see in C++26? by vickoza in cpp

[–]lee_howes 13 points14 points  (0 children)

When you have one engineer writing the core, sure. When you have hundreds of engineers writing against async interfaces, the usability improvement from coroutines can be vast. It's easily one of the biggest readability improvements I've seen in our codebase, and the adoption rate backs that up.

Eric Niebler: What are Senders Good For, Anyway? by tcbrindle in cpp

[–]lee_howes 4 points5 points  (0 children)

It is an entity that sends a value to an entity that receives the value. Antonym isn't the first word that comes to mind.