wg-async
wg-async copied to clipboard
Closure types
-
Brief summary: Various problems arise due to the types of closures and the limitations of closure types.
- Suppose we want a callback of sorts to be notified of some event (network packet received, keystroke, internal event between subsystems)
- Writing a function like
fn notifyLater<F>(listener: F) where F: Fn + Clone...is unwieldy.- It becomes more unwieldy for more closure arguments
- Lots of decisions have to be made about
Fn,FnMut,Clone,Copy,Sync, andSend. But at the time you make these decisions, you haven't written any code yet- Easy to imagine callers will of course supply a
Sendclosure and add that to the requirements. Harder to refactor some existing code so it be used inF: Whatever.
- Easy to imagine callers will of course supply a
- Not sure if we stabilized async closures but I believe we generally continue to expand the surface area of closure types and all their configurations which continues to drive up the cost of callback designs
- caller has to figure out why their closure was (not) inferred to be
Fn,Clone,Copy,Sync, orSend notifyLaterhas to store this closure somewhere (like in astruct) which must now also be generic- Generic requirements leak from functions into implemented traits, and from contained types to containing types. This exposes implementation details that would ideally be erased outside a local scope
-
Analogous problems for derived anonymous types, e.g. futures
-
Pain points like these creates pressure to use third-party crates. But this fragments the ecosystem and complicates debugging projects with different systems, e.g. dependencies
-
Character (if known; see [cast]): Possibly Grace, although a lot of these issues are informed by Swift background rather than C++. I'm uncertain if a different systems background justifies a new character.
-
Key points or morals (if known):
- Anonymous types are hard to use
- The barrier to incrementally adopting async patterns or just "one" API is very high
- Requiring coordination across an entire crate or many crates is a heavy burden
Can you say more about
Suppose we want a callback of sorts to be notified of some event (network packet received, keystroke, internal event between subsystems)
In particular, you didn't mention anything about async -- is this specific to async or a general concern? (Either is ok, just trying to clarify and understand)