[Pitch] Modify and read accessors

I'd rather we just stick with read and modify.

I don't like yield set — the modify operation is not a version of set with coroutines. It is an operation used for both reading and writing, whereas get is solely for reading and set is solely for writing. A more accurate term would be yield get set.

I also think read and modify are better because they're more familiar terms. Even though they aren't officially available, they are used in the source code of the standard library and in other prominent libraries (both official and unofficial) and they have a significant impact on ARC performance, so many Swift programmers are already familiar with the terms.

We could add read and modify without making source-breaking changes by adding an attribute:

@coroutineAccessors
var x: Int { ... }

@coroutineAccessors would indicate to the parser that read and modify can be used in a computed variable's body. (Of course, the actual name of the attribute can be debated.) If read or modify are used in a variable's body but the variable isn't marked @coroutineAccessors, then we could present a Fix-It that adds the attribute.

Alternatively, if we don't like the idea of an attribute that changes how a declaration is parsed, we could make coroutineAccessors an argument:

var(coroutineAccessors) x: Int { ... }

Of course, neither of these are ideal, but they're good enough to get us to Swift 7.


One pain point that has been brought up with the current _read and _modify accessors is that the fact that you can't yield from within a closure. Would it be possible to have an API that lets you work around this?

Maybe something like this?

var x: X {
    read {
        yield withCoroutineContinuation[] { continuation in
            lockedX.withLock { x in
                continuation.yield(x)
            }
        }
    }
}

I also think that the proposal should specify how modify works with property requirements declared on protocols.

2 Likes