Fork me on GitHub
#missionary
<
2021-11-16
>
ribelo22:11:00

in fact, it is often claimed that missionary can be used for something like excel, but how?

ribelo22:11:06

I can't figure it out conceptually.

ribelo22:11:11

I can link multiple ap using reactor, but reactor itself can't be reused as if in another reactor

ribelo22:11:33

(def A1 (atom 1))
(def A2 (atom 1))
(def A3 (m/reactor
         (let [a1 (m/signal! (m/watch A1))
               a2 (m/signal! (m/watch A2))]
           (m/stream! (m/ap (+ (m/<! a1) (m/<! a2)))))))

ribelo22:11:41

but if, for example, A4 should be A3^2 then how do i bite it?

ribelo22:11:34

Do I need to know the whole dag to use reactor?

ribelo22:11:20

making excel with a reagent or other form of reactive atom is a piece of cake

Ben Sless05:11:53

You could make each cell a continuous flow running asynchronously, no?

Ben Sless05:11:12

I don't know why you'd need an atom then

ribelo07:11:00

you probably know what you're talking about, but I don't really understand what I'm talking about 🙃

Ben Sless07:11:17

There's also the possibility both of us are clueless 🙂

ribelo07:11:21

while tasks are simple and seamless, I can't seem to wrap my head around ap

Ben Sless07:11:25

ap = ambiguous process

ribelo07:11:03

I'm not so bad, I deal with RxJS every day

ribelo07:11:13

but I'm going to start reading right away, there's never enough reading

leonoel08:11:02

use m/latest to represent spreadsheet formulas

leonoel08:11:11

(m/ap (+ (m/?< a1) (m/?< a2))) is not the right tool here, even though it seems to work it's suboptimal for this use case

leonoel08:11:37

the Rx equivalent would be (.switchMap a1 (fn [x] (.map a2 (fn [y] (+ x y)))))

ribelo08:11:11

but I have a problem elsewhere and I don't really know how to explain it

ribelo08:11:04

reactor and ap sort of duplicate each other in my misunderstanding

ribelo08:11:03

in the example with excel I don't know if the cell should be represented, by ap or by some atom connected to reactor

leonoel08:11:04

it's fine to use atom and m/watch to represent the inputs of your spreadsheet

leonoel08:11:05

m/latest for formulas, and m/ap for effects

leonoel08:11:56

m/signal! is like .share in Rx

leonoel08:11:25

m/reactor is a kind of transaction engine that ensures change propagations are consistent and glitch-free

ribelo08:11:02

and if it functions is ap with latest, then later I should connect the ui using reactor?

leonoel08:11:59

what is connecting the UI ?

ribelo08:11:48

I understand excel worksheet in such a way that a cell has two roles, it is a store of values / function results, and it displays information to the user

ribelo08:11:01

assuming I'm using react, for example, I need to get the value present in the cell and call (.setState value)

leonoel08:11:40

that's an effect

ribelo08:11:56

I overlooked it

leonoel08:11:38

call .setState anywhere in the cell downstream

leonoel08:11:59

keep in mind signal! is lazy, if there's nothing but signals no effect will ever happen, that's why you need at least one stream! at the end

ribelo08:11:44

maybe I will simplify it, because communicating in a foreign language about such detailed issues is apparently not very effective with me ; )

ribelo09:11:32

I'm just confused about whether I need to use reactor to calculate the result of a function using value taken from several ap, because the result of reactor is a function and not another ap, which I can't reuse as if in another ap. At the same time I would like to separate the whole calculation from the ui and only then, if necessary, use the values currently in the ap and display them in the ui

ribelo09:11:05

maybe something will click in my head after I watch your talk on re:clojure ;)

catjam 2
clj 1
leonoel09:11:12

could you share some code to show how you would approach this problem in Rx ?

ribelo09:11:27

and behavior-subject can simply be dereferenced

ribelo09:11:48

@U053XQP4S don't worry about me not understanding. Thanks for your willingness to help. I'll poke around and at most come back when I have more precise questions.

leonoel16:11:49

@U0BBFDED7 feel free to ask more questions, your feedback is highly valuable

ribelo22:11:28

why is this a bad idea? because i'm sure this is not how it should look like 😉

ribelo22:11:52

overall it looks like it's working

ribelo22:11:19

btw, thanks for your patience and wiki update ❤️

ribelo22:11:08

the problem is that it's glitching, so I must have screwed something up

leonoel08:11:32

@U0BBFDED7 it is glitching because the signals are not managed by the same reactor, you should have a single reactor for the whole app

leonoel08:11:58

(def db_ (atom {:a 1 :b 1}))

(defn expr [k >x]
  (m/latest (fn [x] [:div (str k x)]) >x))

(defn app [>a >b >v]
  (m/latest
    (fn [a b v]
      [:div a b v
       [:div {:on-click #(swap! db_ update :a inc)}
        "inc A"]
       [:div {:on-click #(swap! db_ update :b inc)}
        "inc B"]])
    (expr "A = " >a)
    (expr "B = " >b)
    (expr "A + B = " >v)))

(def main
  (m/reactor
    (let [>store (m/signal! (m/watch db_))
          >a (m/signal! (m/latest :a >store))
          >b (m/signal! (m/latest :b >store))
          >v (m/signal! (m/latest + >a >b))]
      (m/stream! (m/latest render-hiccup! (app >a >b >v))))))

Ben Sless08:11:39

Does that make a reactor a sort of "wiring" context?

ribelo08:11:50

I feel like I'm breaking through a wall with my head, but I'm doing well because I can see a light on the other side

😂 2
ribelo09:11:49

I got it, it clicked!

catjam 3
ribelo09:11:02

again, thanks for your patience @U053XQP4S