I am trying to make this test pass but it hangs, i am trying to zip a discrete signal with a continuous signal, how do i do it
(? (aggregate conj
(m/sample vector
(enumerate (range 3))
(m/watch (atom :x))
)))
=> [[0 :x] [1 :x] [2 :x]]
I think you swapped sample
inputs
ahhh thank you
Is this deref well defined
(def r (atom nil))
(def >a (m/watch r))
(def >b (ap (println (?? >a)) 42))
(reset! r 1)
@(>b prn prn)
=> 42 ; and prints 1
what is the "right" way to sample the output value
deref
is OK in this case because the result is immediately available, otherwise it's not recommended.
how to sample the output value : there's no general answer, it depends how it's meant to be consumed. If you're just testing at the REPL what I usually do is (def it (flow #(prn :ready) #(prn :done)))
and then @it
each time :ready
is printed, and (it)
to cancel
thanks
n and t stand for notify and terminate?
yes
this test passes
(tests
"backpressure 3 w latest"
(def !a (atom 0))
(def >a (m/watch !a))
(def >z (ap (?? >a)))
(def !z (>z #(println :ready) #(println :done)))
(reset! !a 1)
@!z => 0
@!z => 1
)
this test fails with a crash, one line different - calls m/latest
(tests
"backpressure 3 w latest"
(def !a (atom 0))
(def >a (m/watch !a))
(def >z (m/latest identity (ap (?? >a))))
(def !z (>z #(println :ready) #(println :done)))
(reset! !a 1)
@!z => 0
@!z => 1 ; boom
)
Execution error (ArrayIndexOutOfBoundsException) at missionary.impl.Latest/deref (Latest.java:88).
Index -1 out of bounds for length 1
is this a bug
I'm also surprised that I get 0 in both tests when reading !z the first time, i would expect it to sample the latest value immediately if I understand correctly the model
(m/latest identity flow)
should not change the behavior of input, so bug it is
the first value is 0 because ap
is discrete. To turn it into continuous you can disable backpressure and only keep latest values with (m/relieve {} flow)
ohhh i did not realize ap was discrete, that changes a lot, thanks
what is the {} function meaning here? I had used (defn skip [a b] b) with relieve
oh, default value if not in map
yes
good one
I was thinking that with continuous signals the work was only done when asked for This test runs the println effects even though I did not sample
(tests
"when does the work happen"
(def !a (atom 0))
(def >a (m/watch !a))
(def >z (m/relieve {} (ap (println 'work1) (let [a (?? >a)] (println 'work2) a))))
(def !z (>z #(println :ready) #(println :done)))
(reset! !a 1)
(reset! !a 2)
;@!z => 2
)
work1
work2
:ready
work2
work2
So does that mean it will eagerly push inputs through?perhaps I should not be mixing continuous and discrete
you can mix continuous and discrete, but the discrete parts will be run eagerly
you can only be fully lazy if you have continuous operators all the way down, watch
latest
signal!
, ie the good old spreadsheet model
how do I (map inc) over a continuous signal
latest
Oh ok so my crashing test was kind of bogus anyway because I was accidentally mixing discrete and continuous. Everything works fine if I keep it continuous only
It's still a bug, it should not crash
(ap (?? (f (?? >a))))
discrete bind
what is continuous bind
I'm not clear if it's possible to do actually
What should it do ?
The continuous time bind confuses me right now, but the discrete time bind I would expect to pass this test: use a >control signal to toggle between signals >p and >q at runtime
(defn bind [>a f]
(ap (?? (f (?? >a)))))
(tests
"discrete bind"
(def !p (atom 1))
(def !q (atom 2))
(def !control (atom :p))
(def >p (m/watch !p))
(def >q (m/watch !q))
(def >control (m/watch !control))
(def >cross (bind >control (fn [c]
(case c :p >p :q >q))))
(def >z >cross #_(m/zip vector >p >q >cross))
(def !z (>z #(println :ready) #(println :done)))
@!z => 1
(reset! !control :q)
@!z => 2 ; nil
)
Ignore the !! sorry
it's close to ?!
bed time here, I'll sleep on that
Changing bind to use ?! caused the above discrete test to pass
(defn bind [>a f]
(ap (?? (f (?! >a)))))
that's a really interesting observation also