SE-0293: Extend Property Wrappers to Function and Closure Parameters

Ah, when I've been talking about "library authors," I've mostly been thinking of an intermediate between the property wrapper author and the ultimate end user (e.g., someone writing a SwiftUI utility library who uses the @Binding wrapper on their properties and function parameters). These are the authors that I think are likely to have internalized a rule to the effect of "adding a wrapper attribute does not expose the backing storage as API," an assumption which this proposal would break.

I alluded to this briefly in my first post (and @Lantua has mentioned something similar), but IMO the issue of unapplied references as 'solved' in this proposal actually decreases author freedom. Authors of parameter-wrapped functions have no choice but to expose the backing storage of the wrapped parameter as API, whereas for wrapped properties they have total control (and the default is that the storage is not exposed, even outside the type itself, not to mention publicly).

Punting on this part of the proposal would preserve the status quo. Authors who really do want to expose the backing storage for their wrapped parameters are free to create multiple entry points. It requires a little boilerplate, but we've historically been fine with requiring boilerplate in order to make public API explicit (e.g., forcing the synthesized memberwise initializer to be at most internal).

@hborla's posts in the pitch thread (and your examples here) provide several alternative (and compelling!) solutions to some of the problems I've raised with exposing the backing storage, but there doesn't seem to be much of a consensus around which directions are most promising. Furthermore, the answer supplied in this proposal to the unapplied references question would cut off evolution in directions that I think are promising, e.g.:

(That is, even if we decide that exposing the backing storage is desirable, it doesn't obviously follow that the backing-storage version of the function should receive the blessed foo(arg:) spelling as opposed to the 'as-called' version of the function.)

2 Likes