ds300 / ds300/derivablejs

Change reactor lifetime API to be more expressive

Open
#62 3 comments 0 reactions 0 assignees View on GitHub
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

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.