Fork me on GitHub
#missionary
<
2022-07-30
>
Dustin Getz19:07:10

How do I add an initial value to this

(defn ticker "tick randomly at intervals up to n ms wide" [n]
  (m/cp
    (loop []
      (m/amb
        (m/? (let [r (rand-int n)] (m/sleep r r)))
        (recur)))))

Dustin Getz19:07:47

This throws "Reactor failure: Error: Unsupported operation." not sure why

(defn ticker "tick randomly at intervals up to n ms wide" [n]
  (m/cp
    (loop [r 0]
      (m/amb
        r
        (recur (m/? (m/sleep r (rand-int n))))))))

leonoel19:07:07

amb and ? are illegal in cp

Dustin Getz19:07:06

thanks, yeah m/ap works. I want this continuous so the sleeps will be started on sample, because i am doing this in an inner loop of 10k dom elements

Dustin Getz19:07:26

i have exceeded the browser's ability to keep up with the eagerness, trying to figure out how to make it lazier

Dustin Getz19:07:55

i'm good, will ask on monday

leonoel19:07:48

use a shared raf-based continuous clock and make each element's color a random function of time

Dustin Getz12:07:53

Struggling to mathematically model each cell in a grid getting a separate random timer, I guess it is an incoherent requirement as the timers become coupled to the consumer's ability to keep up

Dustin Getz12:07:51

If the cell is a function of [t x y] it's easy

reedho09:08:12

First time see m/cp here, is it in b27 ? Whats difference with ap ?

leonoel10:08:15

https://github.com/leonoel/missionary/issues/26 compared to ap, cp is fully lazy but more restricted (only ?< is allowed, not ? and ?>)

👍 1
Dustin Getz12:08:53

Why is m/? not allowed in m/cp?

Dustin Getz12:08:05

Is this correct: m/?> (concat) is not sensible in m/cp because concatenating two continuous flows doesn't make sense: a continuous flow models a "current/latest state" which doesn't terminate under normal conditions, and continuous flows are always defined from t=0 with an initial value, so stacking two simultaneous continuous flows doesn't make sense

1
❤️ 1
Dustin Getz12:08:56

As to m/? in m/cp, if this println makes sense (def !x (atom 0)) (m/cp (println (m/?< (m/watch !x)))) then why not an async println backed by a task?

Dustin Getz12:08:44

The root lesson seems to be "side effects don't make sense in continuous time"

leonoel12:08:07

the mismatch is async vs laziness

1
leonoel12:08:37

cp must be defined at every point in time, an asynchronous computation is not defined until it terminates, therefore an asynchronous computation is essentially eager

Dustin Getz12:08:21

i agree with that – and the natural conclusion of that argument seems to be that the println in m/cp should be illegal as well?

Dustin Getz12:08:27

setting aside philosophy; implementation wise could (m/cp (m/amb 0 (m/? (m/sleep (m/?< (m/watch !x)) ::x))) either model a pending value, or leave the 0 in place until ::x is available? is there a technical reason i've missed

Dustin Getz12:08:12

understanding that the sleep does not begin until sampled, and the ::x is not seen until sampled, which may not even be an issue depending on the nature of your effects

leonoel12:08:30

What triggers the sleep in this example ?

😮 1
Dustin Getz12:08:48

(comment
  "Thought experiment: can m/amb and m/? be defined sensibly in m/cp?"
  (def !x (atom 0))
  (def <y (m/cp (m/amb 0 (m/? (m/sleep (m/?< (m/watch !x)) ::x)))))
  (def !it (<y #(! ::notify) #(! ::terminate)))
  % := ::notify
  @!it := 0
  ;% := ::notify -- sleep cannot begin until sampled, nothing to notify
  ;@!it := ::x
  )

Dustin Getz13:08:56

you could model pending though and notify pending