Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Should we allow property to emit multiple "current" values/errors to the first subscriber? #142

Open
rpominov opened this issue Sep 5, 2015 · 3 comments

Comments

@rpominov
Copy link
Member

rpominov commented Sep 5, 2015

As mentioned in the docs both stream and properties may emit current* values/errors. And while streams has no special treatment for current events, properties treat them specially: When a property gets an event during activation (i.e. "current" event), property doesn't dispatch it, but only saves in the cache. Then, at the end of activation, it calls subscriber with the current event form cache (if any). As a result, property ignore multiple "current" events from its source, and dispatch only last of them.

(*) By "current" I mean all events pushed to the subscriber immediately (synchronously) after subscription.

var streamWithCurrents = Kefir.stream(function(em) {
  em.emit(1)
  em.emit(2)
  em.emit(3)
})

streamWithCurrents.log('a')
streamWithCurrents.log('b')

// a <value:current> 1
// a <value:current> 2
// a <value:current> 3

// (b gets nothing)
var streamWithCurrents = Kefir.stream(function(em) {
  em.emit(1)
  em.emit(2)
  em.emit(3)
})
var property = streamWithCurrents.toProperty()

property.log('a')
property.log('b')

// a <value:current> 3
// b <value:current> 3

If we fix that, the second example will output:

// a <value:current> 1
// a <value:current> 2
// a <value:current> 3
// b <value:current> 3

Related #140

@cefn
Copy link

cefn commented Sep 5, 2015

Property behaviour as a 'cache' adds significant value to the stream-oriented API.

I think of Properties as something like a catchup, where

  1. if you were watching from the beginning then a Stream and a Property behaves identically
  2. if you decided to watch later, then with a Stream you only get future events, but with a Property you get the (cached) last event as well as future events

The problem with the existing behaviour of flatten (to insist on uniqueness of 'current' within a single stack and hence dispose of items during activation) is that 1. is violated.

I have encountered a 'semantic' definition of Property which I believe is alluded to in e.g. http://rpominov.github.io/kefir/#current-in-streams and http://rpominov.github.io/kefir/#about-observables which isn't as simple as the procedural definition above and relates to their role describing the unfolding of a value over time (and hence an implicit notion of event-loop simultaneity).

From my use of Kefir so far, the procedural definition in 1. and 2. above satisfies my uses of Properties, and if a 'single-value per eventloop' behaviour was needed, (e.g. for efficiency where a million stale events need to be ignored), this could be an explicit stream transformation, perhaps based on a strategy to unroll the stack (like https://github.com/kriskowal/asap) and deliver only a single event when the unrolled stack event is hit.

@rpominov
Copy link
Member Author

rpominov commented Sep 6, 2015

The following is mostly answer to https://github.com/rpominov/kefir/issues/140#issuecomment-138010478.

Yeah, it seem like we have different mental models for the property. To me streams represent bunch of points in time, while property represents continuous line. And it quite natural to me, that when we apply a transformation to a bunch of points, we get a new bunch of points, and when apply it to a line, we get back a new line.

And again, in real world cases, I often want property to remain property after transformation. Say property representing input value, scroll position etc.

But the concept of the property in FRP is certainly not explored and established well enough. Some FRP libs doesn't have it (Rx, Most), some have only properties and not streams, some have both (Bacon, Kefir). I think property, in the form we have it, was invented by @raimohanska in Bacon, and supposed to have similar semantics to behaviors from original FRP idea by Conal Elliott.

And maybe your mental model of properties is indeed more useful. Although doesn't seems like so to me at this point. I wonder what others think about it. You might want to open this discussion in Bacon repo, as it has wider community.

if a 'single-value per eventloop' behaviour was needed, (e.g. for efficiency where a million stale events need to be ignored)

I think main reason for this is semantics: if bunch of changes happened "simultaneously", and we look at property like at continuous line, all but the last events doesn't matter as they doesn't affect form of the line. And from other perspective, if we pretend for a moment that we don't have laziness (activation) in properties: the contract is, when we subscribe to a property, we get current value and subscribe to further changes — in this case, it doesn't make much sense to get multiple current values at subscription.

Another reason is that we want to avoid "first subscriber consumes current values" situation, at least for the properties.

@cefn
Copy link

cefn commented Sep 7, 2015

I think this partly depends how you define line. Conventionally you can have a plot which contains a vertical discontinuity (e.g. a value of 50 is momentarily at 100 then back to 50 with no time passing).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants