Skip to content
jasonyandell edited this page Aug 14, 2011 · 4 revisions

Implements join calculus on one or more plans generated by using and and then.

static function when(valueClass : Class, plans : Array) : IObservable.<*>

Remarks

Joins are very similar to zip in many ways, albeit on a greater scale. Joins allow a subscriber to react differently depending on the order in which it received input.

A join is made up of one or more plans, which are made from a pattern (one or more IObservable sequences) and a selector. Much like the selector in zip accepts two values and returns the output value, so must a plan’s selector accept one value for each sequence in the pattern.

Everytime a value is received from any sequence from a plan being joined, the plans are checked for a match in a top-down fashion. A plan is a “match” if at least one value is available for every sequence in it’s pattern. The sequences within a plan can be received in any order.

If no plan is matched, the value is kept for later. Once a plan is matched, the values are passed to the plan’s selector and the return value is emitted to the subscriber. Any values used in the match are removed from the “queue” for that sequence.

If a sequence is shared by more than one plan, priority will be given in order of the plans. See the second marble diagram for an example.

The plans in the marble diagrams below each have 2 sequences, but this is not always the case. Plans can have as little as one sequence with no upper limit. Furthermore, plans being joined to not have to share the same number of source sequences. For example, you could have a plan that matches against 1 sequence that acts as a cancellation for another plan that uses 5 sequences (though amb would be a better solution for that particular problem).

Marble Diagrams

vs, ws = plan 1
fa     = selector for plan 1
xs, ys = plan 2
fb     = selector for plan 2

│ vs ───o───────────o────────/
│       └──┐
│ ws ──────o───────────────────/
           │                
│ xs ────o─│───────────────o─────/
│        └─┼───────┐  ┌────┤
│ ys ──────│───────o──o────│────────/
           │       │       │        │
        fa(v,w) fb(x,y) fb(x,y)     │
           │       │       │        │
  zs ──────o───────o───────o────────/

In the above example there are two plans (vs+ws and xs+ys), each with two sequences. The last vs value is never used because no value is received from ws.

ws, xs = plan 1
fa     = selector for plan 1
xs, ys = plan 2
fb     = selector for plan 2

│ ws ───o────────────────o─────/
│       └──┐             └─┐
╞ xs ──────o─o─────────────o─────/
│          │ └─────┐       │
│ ys ──────│───────o──o────│───────/
           │       │       │       │
        fa(w,x) fb(x,y) fb(x,y)    │
           │       │       │       │
  zs ──────o───────o───────o────────/

In the above sample, xs is shared by both plan 1 and plan 2. The second value from ys is never matched, even though it came first, because plans are always matched top-down. The next value to arrive was from ws, which yielded no matches (ws and ys are not shared in a plan). After that, a value is received from xs which matches plan 1 (ws, xs).

Return Value

IObservable.<valueClass>

Examples

```as3
```