freenode
Languages & Toolchains

Swift pitch adds single-yield functions beyond accessors

A language proposal would let ordinary functions suspend after handing out a value, then resume for cleanup, aiming to shrink with-style closure pyramids.

Swift language designers are considering single-yield functions: ordinary methods and free functions that act as one-shot coroutines, yielding a value to the caller and suspending until that access ends, then running cleanup to completion.

Meg Gupta pitched the feature as a generalization of today’s yielding accessors. A function would declare a yield in the result position for an owned value, a borrow, or an inout binding. Execution runs to the yield, the caller uses the value, and the coroutine resumes afterward so deferred work and resource release still happen in order.

The practical draw is API shape. Many standard-library and Foundation with* helpers exist mainly to bracket temporary access inside a closure. Yielding versions could flatten nested callbacks for spans, buffers, and similar short-lived views, while still guaranteeing the provider’s teardown runs. Swift Testing maintainers already see a path to safer attachment buffers without today’s unsafe byte-handoff entry points. Server and concurrency authors likewise want the pattern for buffer-pool I/O once async single-yield functions exist.

Not everyone wants a new declaration form. One counter-proposal argued that noncopyable wrapper types plus an explicit “must finish” consumption step could encode the same lifetime protocol without special function syntax. Others called the feature a natural extension of yielding accessors and focused on naming: whether the marker should read yield, yielding, or a yields(...) clause more like throws, especially if a distinct return type is ever added beside the yielded value.

Open design questions include how strictly nested yields resume (stack order), how defer interacts with the yield point, and what it would take to support throwing or async work after the yield so task groups and similar scoped APIs could adopt the model. Multiple yields, and thus generators, remain a stated future direction rather than part of the initial pitch.

If accepted through Swift Evolution, the change would mainly affect library authors who today force callers into closure pyramids to keep ownership and cleanup correct, and callers who want those temporary values as ordinary bindings instead.