wg-async icon indicating copy to clipboard operation
wg-async copied to clipboard

Closure types

Open drewcrawford opened this issue 4 years ago • 1 comments

  • 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, and Send. But at the time you make these decisions, you haven't written any code yet
        • Easy to imagine callers will of course supply a Send closure and add that to the requirements. Harder to refactor some existing code so it be used in F: Whatever.
      • 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, or Send
    • notifyLater has to store this closure somewhere (like in a struct) 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

drewcrawford avatar Mar 19 '21 00:03 drewcrawford

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)

nikomatsakis avatar Mar 19 '21 14:03 nikomatsakis