[Pitch] Transactional observation of values

digressing a bit from the termination/optionality questions, i wanted to re-highlight some issues with the offered initial implementation. specifically:

  1. if the observed sequence hasn't yet changed, only one iterator will see the initial value (noted here)
  2. if any of the Observable dependencies in the closure change in between a read of the closure and an iterator's next suspension awaiting a subsequent 'will set' trigger, the sequence functionally breaks as it no longer produces any new values (pointed out here)

are these 'just' bugs, or do they impinge upon the design considerations in a more meaningful way?

and, a few other thoughts/questions inspired by the implementation PR:

  1. currently the behavior to produce new values uses a 'pull' model, in the sense that when a 'will set' event occurs, each iterator effectively performs a fetch of a new value from the 'source' isolation. thus, N pending iterators means N invocations of the Observed closure. this raises both performance questions, and questions about whether the stated aim of the proposal that 'multiple iterations of the same sequence from multiple tasks will emit the same values at the same iteration points' is actually achievable with this model. i.e. if multiple iterators must invoke the closure separately, and additional changes to the input values could interleave between them, they will not necessarily 'see' the same value when they actually perform the read.
  2. if the closure and iterator are both non-isolated[1], it seems likely to undermine the type's goal of providing 'atomic' views into the derived sequence of values. in particular it seems like you essentially lose the 'enqueue on the source isolation' strategy of defending against 'tearing'. how are developers to deal with this? wrap the entire closure invocation in a lock? is supporting this use case important/valuable?
  3. what if the closure has some conditional control flow in which no Observable value is read? e.g.
    var nonObservableCondition = true
    Observed { 
        if nonObservableCondition {
          return "sequence over?"
        } else {
          return person.name
        }
    }
    
    today it seems like the sequence will just stop producing values, but not actually end. can such cases be detected and surfaced to developers?

  1. which i think implies the Observable stuff in the closure must (or at least should) be Sendable ↩︎

1 Like