SE-0447: Span: Safe Access to Contiguous Storage

(Dons review manager hat)

They're proposed now to gather feedback on the shape of the API, most of which is independent of the deep details of lifetimes. That's happening here, which is good. When the API "ships" is a separate matter.

(Dons personal-opinions hat)

I don't agree with your assessment above. The span provided to the closure has a lifetime tied to the execution of that closure's body: this describes the semantics that the with-style functions have had since Swift 1.0, and persists into newer APIs like withTaskGroup, despite not having a way to express this in the language. It also describes how arguments of non-@escaping function type work in practice.

With an expressive system to describe lifetime dependencies, one can invent other lifetimes for higher-order functions. We should not do anything here that would invalidate the simple description above, because it would undermine progressive disclosure in the language and create an unnecessary rift between existing Swift APIs like withUnsafeBufferPointer and the newer APIs proposed as part of this work on lifetimes. If the obvious lifetime semantics of withSpan don't work with the more general lifetime dependencies, it's the lifetime dependencies proposal that should be adjusted. @Joe_Groff discusses lifetimes and the higher-order generalizations more in SE-0446: Nonescapable Types - #28 by Joe_Groff.

I'd actually take this one step further: I think we should consider adding withSpan to the standard library. It provides clear scoping for the lifetime of the span, fits in with existing APIs cleanly, and offers a direct safe replacement to a swath of heavily-used unsafe APIs. As much as I'd like to use a property solution (span or storage or whatever we call it), it is a very different model to what we've had in Swift for a decade and it pushes developers further down the path of having to understand the lifetime model than withSpan.

Doug

13 Likes