[Pitch] Observation

I'm excited for this direction, it looks very promising for some (non-SwiftUI) problems in a codebase I work on. With Holly's recent update about the need for type wrappers (likely) being obviated by declaration macros, I wondered if you had had any further thoughts about what a macro-based approach for Observable would look like here?

Holly and I have been collaborating on some updates to this for the use of macros. I am in the process of revising the pitch; stay tuned - some of the feedback here and from direct sources has been quite helpful and I think it is turning into something pretty awesome.


Waiting with bated breath! :)


Hum… this is a great idea but I suggest “Observable” as a Swift keyword like “async”, more at language core.

observable class FoodStore { 
    observable var foods: [Food] = []
    var nonObservableProperty: String = “”
var foodStore = FoodStore()

for await change in foodStore { … }
for await change in foodStore.foods { … }

Or just

class FoodStore { 
    var foods: [Food] = []
observable var foodStore = FoodStore()

for await change in foodStore { … }
for await change in foodStore.foods { … }

Or… let (constant), var (variable), obs (observable)

class FoodStore { 
    obs foods: [Food] = []
    var nonObservableProperty: String = “”
obs foodStore = FoodStore()

for await change in foodStore { … }
for await change in foodStore.foods { … }
class NotificationStore {
    static obs shared = NotificationStore()

    obs lastNotification: Notification? = nil
for await notification in NotificationStore.shared.lastNotification { … }

Granted observation could be more of a runtime level feature but that would mean that the cost of making something observable would impact the potential complexity and code-generation of non-observable things. I'm not sure (even as powerful as observation is) that meets the bar of what it would mean to be language level. Instead it makes a lot more sense to have the implementation of observation first off be approachable (that folks can tinker on it without needing to build the compiler or runtime libraries from scratch) as well as integratabtle into other use cases more than just observing async sequences of values (e.g. SwiftUI's tracking of values to observe). Macros give us the power of the compiler without needing to go to the extent of inventing new things like obs.

I totally agree with you that making a type able to be observed should be as dead simple as just tossing on some sort of decorator. Hopefully next week I will have the new pitch ready - truth be told it is a pretty extensive document covering all of the nooks and crannies of how things should be observed and what that means so it has taken me a bit to re-write it and explore those bits and the implications for performance and integration. One of the key areas that I think will help is that the new pitch has detailed examples for almost all of the different bits.


I have been a bit under-water with a few tasks - but some of the changes are in a pull request pending on the compiler: [WIP] Initial draft of observation by phausler · Pull Request #63725 · apple/swift · GitHub. It was requested previously to provide some stuff to tinker with and see how it works - right now I am finishing up some of the macro integration (which is still a bit broken in that PR) so it is not fully ready just yet. Here soon @nnnnnnnn and I will be wrangling up a new rendition of the pitch to bring forth some of the changes to the pitch.

The plan of record is to build up the implementation along side the pitch such that it can be used as an experimental module, both for integration into other parts, as well as stand-alone evaluation.

Thanks for your patience.


Thank you for the update. I've been lurking in the implementation details since I noticed it and I'm really exiting to see where all this is heading.

I have a few questions that may or may not influence the direction the implementation is following:

  • Will there be a solution for lazy initialization as needed for SwiftUI?
  • Will there be a good default for discarding duplicates as an opt-in/out?
  • Can the macro provide the synthesis for the protocol conformance, so that we don't have @Observable attribute near the protocol conformance : Observable?!

While not particularly related to observation, but some simple values could use some form of a 'binding', which either assigns the value to some property or is a referencing structure similar to SwiftUI's Binding property wrapper.

Will we possibly get some ergonomic solution for this to bind observed values as part of the implementation, or at least as a future direction?
Maybe a property wrapper like macro could do both tricks?! :thinking:

1 Like

This is nice but really Swift needs a Flow like library that is built from the ground up with async await. Thus, a Combine like lib but with

  • Multi platform support
  • 100% interop with async functions

Take a look at Async Algorithms


In game development, the order in which interested parties receive events is often crucial. Will observers receive notifications in a way that's deterministic across platforms?

Better yet, would it be possible to make something like an OrderedObservable which allows for fine-tuned sorting of the observers? This would be a huge benefit to areas such as turn-based game design.

At any rate, and as others have said, I'm very exited to see where all this goes!


For those interested; after a ton of work revising things and accounting for a lot of the initial feedback here and from folks directly relaying info, there is a newly minted version of this pitch here.

The pitch shifted a touch more towards transactional based changes (since we feel that is more appropriate for observation) and refined a lot of the naming to more clearly indicate both the utility of specific APIs and fall more in-line with other existing APIs. The SwiftUI part is pretty much unchanged from the initial pitch here. In addition we have some initial versions posted as a pull request which is nearly ready for merging.

We think we are really close to a great solution here and would like to drive it forward with yall's help and feedback.


I think the changes look fantastic! The api is so clear and straightforward.