Missionary primitives fit into three categories:
- continuous flow, m/?< (switch)
- m/watch, m/latest, m/cp
- m/observe
- m/reductions, m/relieve
- discrete flow, m/ap - switch and concat
- m/eduction — discrete flows model event streams, which are simply async sequences
Note: These are all referentially transparent primitives that construct values or "recipes" that describe effects.
Publishers = "observable sharing," this is what gets you from Tree to DAG, and is no longer pure functional
- m/signal
- m/stream
- m/memo (task)
Note:
- the difference between effect descriptions and observables is memoization, which means state
- signal/stream return stateful objects (identity) which carry the memoization.
- this section describes the next iteration of Missionary, which is under active development as of this writing (2023 Feb 24). Leo figured out how to remove m/reactor (see leonoel/missionary#70).
m/memo
is new, andm/signal
/m/stream
no longer get a!
- Discrete ports:
- m/dfv = mutable single assignment reference
- m/mbx = mutable queue reference. Fire and forget. Unbounded queue. Not backpressured [bad]. like an actor (actor = process + mailbox). All actor systems have mbx. All actors are fire and forget. Lack of backpressure is a reason Rich doesn't like actors.
- m/rdv = channel/queue with backpressure; only put one value at a time until taken
- Continuous ports:
- atom – already exist so missionary doesn't add
- this is a recursion primitive in practice - for cycles
- atom – already exist so missionary doesn't add
Note: in Electric Clojure, ports are constructed in userland; the compiler does not emit ports. State and coordination is fully in userland control!