Change reactor lifetime API to be more expressive
- Dominant language
- JavaScript
- Stars
- 518
- Forks
- 23
- PR merge metrics
- No merged PRs in 30d
Description
Reactors are like people—like almost any animal, actually—in that they are born and then they die, and during this time they can be either awake or asleep. When they are both alive and awake, they actively listen for and react to changes in their environment.
At the moment you define a birth date and death date for a reactor using the `from` and `until` conditions, and you define a wake time and sleep time using the `when` condition. These both declaratively describe spans of time, and yet they are not equivalent ways of doing that.
`from` and `until` are more flexible than `when` for delimiting a span of time. The reactor becomes alive as soon as the `from` condition is truthy. But then, no matter how the `from` condition changes, the reactor stays alive until the `until` condition becomes truthy (unless it was truthy to begin with, in which case the reactor never comes to life 😢 ).
To illustrate, if we were to use the `when` condition for defining life-spans, the reactor would come to life when the `when` condition becomes truthy and die when it becomes falsey.
i.e.
x.react(f, {when: alive}) // `when` controls the life-span, not the awake-span
is equivalent to
x.react(f, {from: alive, until: alive.not()})
But if we introduce independent variables for `from` and `until`:
x.react(f, {from: foo, until: bar});
How can we convert that back to a `when` condition? `when: foo.and(bar.not())` doesn't work because `foo` could change back to a falsey value before `bar` becomes truthy. I think it is not possible to convert, because there is another implicit piece of atomic state which you cannot reference: the state of *whether `foo` has been truthy since the reactor was defined*.
So `{from: foo, until: bar}` is really equivalent to `{when: fooHasBeenTruthyAtSomePoint.and(bar.not())}`
---
So I think it should be possible to describe life-spans with a `when` condition, because sometimes that's convenient, and awake-spans with `from` and `until` conditions, because sometimes that's convenient.
Here's the canonical format I propose:
```
blah.react(f, {
alive: {
from: foo,
until: bar,
},
awake: {
from: baz,
until: quux,
},
})
```
But `when` will be allowed in the `alive` or `awake` time span descriptors, as a replacement for the `from` and `until` conditions.
```
blah.react(f, {alive: {when: foo}})
// or, as a shorthand:
blah.react(f, {alive: foo})
```
So far I haven't mentioned `skipFirst` and `once` from the existing scheme. Still thinking about that.
Contributor guide
Assessment
This issue has not been assessed yet.