I'm thrilled to see this refined version of the swift-atomics package coming to the standard library.
The proposal covers what I'd expect and the API looks reasonable to me. I didn't get around to actually writing working code against it, but I did review some of the C++ atomics-handling code in the concurrency library to envision how it would look with this proposal. The proposal is mirroring the C++ atomics APIs very closely, which I think is okay: we're leveraging the C++ memory model, and there's a lot of benefits to cross-language consistency for something this complicated. I suspect that we'll want some slightly-higher-level APIs in the future, but that won't obviate the need for what's in this proposal.
I'm glad to see AtomicLazyReference
here as one of these "higher-level APIs". I think it should be conditionally Sendable
, i.e.,
extension AtomicLazyReference: Sendable where Instance: Sendable { }
The thread-safe lazy initialization pattern is listed as:
var _foo: AtomicLazyReference<Foo> = ...
// This is safe to call concurrently from multiple threads.
var atomicLazyFoo: Foo {
if let foo = _foo.load() { return foo }
// Note: the code here may run concurrently on multiple threads.
// All but one of the resulting values will be discarded.
let foo = Foo()
return _foo.storeIfNil(foo)
}
but IIUC that _foo
should be a let
rather than a var
, right? And it's fairly likely that one would then want atomicLazyFoo
to also be nonisolated
, so it can be referenced concurrently.
It doesn't need to be in this proposal, but this cries out for a macro so one could do:
@AtomicLazy
nonisolated var atomicLazyFoo: Foo = Foo()
to apply the above pattern.
An additional note with regards to the Law of Exclusivity, atomic values should never be declared with a var binding, always prefer a let one.
As noted by others, this is a pretty big foot-gun, especially since we've been teaching folks for years that var
means mutable and let
means immutable, and atomics feel like value types even though identity is critical. At the very least, we'll want some compiler warnings here to help guide folks away from var
for these atomic types. It would be better to generalize this notion with an attribute, because I suspect we're going to have other noncopyable types like this in the future.
Doug