leonoel / missionary

A functional effect and streaming system for Clojure/Script
Eclipse Public License 2.0
630 stars 26 forks source link

continuous switches #26

Closed leonoel closed 1 year ago

leonoel commented 3 years ago

Problem : switching flows is currently possible with ap/?! but the behavior is discrete and eager, which is not always what we want.

Solution : provide a new macro cp (continuous process) returning a continuous flow, with ?! available as a forking operator. Like in ap, ?! runs provided flow, forks current computation and cancels previous branch for each successive value, but each branch is run lazily.

Example :

(def numbers-channel (atom 0))
(def strings-network (atom "hello"))
(def remote-control (atom :strings))

(def tv
  (m/cp
    (case (m/?! (m/watch remote-control))
      :numbers (m/?! (m/watch numbers-channel))
      :strings (m/?! (m/watch strings-network))
      :both (m/?! (m/latest vector (m/watch numbers-channel) (m/watch strings-network)))
      :static-noise)))

(def it (tv #(prn :ready) #(prn :done)))                  ;; :ready
@it #_=> "hello"
(reset! remote-control :numbers)                          ;; :ready
@it #_=> 0
(swap! numbers-channel inc)                               ;; :ready
(swap! numbers-channel inc)
@it #_=> 2
(swap! numbers-channel inc)                               ;; :ready
(reset! remote-control :both)
(reset! strings-network "world")
@it #_=> [3 "world"]
(reset! remote-control nil)                               ;; :ready
@it #_=> :static-noise
leonoel commented 1 year ago

Released in b.27