I've recently been exploring the pattern of usings structs with stored closures instead of protocols for types that are only realistically intended have a "live" and a "test" implementation. (Inspired by the fine folks at PointFree).
For example:
struct NetworkService {
var sendRequest: (_ request: URLRequest) async throws -> Data
}
extension NetworkService {
static func live(session: URLSession = .shared) -> NetworkService {
NetworkService(sendRequest: { (request: URLRequest) in
// Do the thing...
})
}
}
The biggest hangup I've run into is that it's not currently possible to provide argument labels for closure properties. For example I couldn't cleanly change the signature of sendRequest(_:)
to send(request: URLRequest)
. The issue only gets worse for closures that take multiple arguments.
A colleague of mine found this Swift Evolution proposal to remove the significants of function arguments from the type system circa Swift 3.
In the linked "Additional Commentary" a future direction is proposed where argument labels could be added to closures properties. Leaving space for that future without causing source breaking changes is explicitly called out as reason for requiring the _
before "cosmetic" closure labels in the current implementation.
I'd love to see the work outlined in the additional commentary picked up, but I don't have the compiler expertise to understand the scope of the change or the potential impact on things like ABI.
Is it still realistic to add this feature to Swift?