Fork me on GitHub
#missionary
<
2023-07-16
>
kawas12:07:16

Been playing with flows, trying to mimic code from RxJava. As a result, I wrote some helping functions (just for private use). Do you think it is idiomatic Missionary ? Anything I did wrong ? https://gist.github.com/kawas44/201a4cc00efc3a912ea0fcbbeb3e77cc

❤️ 2
Dustin Getz12:07:28

I know this is a lot of work but it would help to see inline tests documenting the intended usage

Dustin Getz12:07:08

Superficially, helpers like timer and flat-map do not really save you anything over inlining into the calling m/ap block – timer saves only one form by eliminating the m/? at the cost of less generality; flat-map also offers imo no obvious value over using the forking macros directly which are more expressive and superior syntax

Dustin Getz12:07:40

Here are my helpers so far https://github.com/hyperfiddle/electric/blob/master/src/contrib/missionary_contrib.cljc. Leo's official comment on the matter of including higher level combinators in missionary itself is this: https://github.com/leonoel/missionary/issues/28#issuecomment-1544458866 . I think they should be at least documented (as everyone will need to derive them anyway as part of their learning journey, like in a math textbook). We also have https://github.com/hyperfiddle/electric/blob/master/src/contrib/missionary_core_async.cljc (which are badly named and need review).

👍 4
Dustin Getz12:07:05

just is merely a rotated m/seed, what is the value over just writing m/seed?

Dustin Getz12:07:29

from-future is questionable because it hardcodes the threadpool strategy m/blk . Depending on the workload, which is either compute-heavy (i.e. a slow datascript query) or IO-heavy (mostly parked and waiting on IO) you need to configure an appropriate executor. [wrong] I see little value over just inlining the implementation.

Dustin Getz12:07:39

In a way I wonder if the urge to create these (or port from RxJava, whatever) stems from a type tetris mindset (perhaps subtly originating from the Java port)? If you allow me to label this the "haskell style", that style only works if there is a checker because you end up with an explosion of combinators with slightly differing types. Part of the value of m/ap (which has syntax for both tasks and flows) is that it is universal

👍 2
leonoel12:07:50

This implementation of subscribe-on is closer to what Rx does, if I understand correctly

(defn task-subscribe-on [exec task]
  (m/sp (try (m/? task)
             (finally (m/? (m/via exec))))))

(defn flow-subscribe-on [exec flow]
  (m/ap (try (m/?> flow)
             (finally (m/? (m/via exec))))))

(defn subscribe-on!
  ([exec on-next flow]
   (subscribe-on! exec on-next #(do %) #(do %) flow))
  ([exec on-next on-error flow]
   (subscribe-on! exec on-next on-error #(do %) flow))
  ([exec on-next on-error on-complete flow]
   ((->> flow
      (flow-subscribe-on exec)
      (m/reduce (fn [_ x] (on-next x)) nil)
      (task-subscribe-on exec))
    on-complete on-error)))

(defn cb [x] (prn (Thread/currentThread) x))
(subscribe-on! m/cpu cb cb cb (m/seed (range 10)))

🙏 2
leonoel13:07:51

> from-future is questionable because it hardcodes the threadpool strategy m/blk That's fine, the thread pool is awaiting the future, not running it. It is purely IO so m/blk is what you need here.

👍 2
🙏 2
kawas15:07:48

> just is merely a rotated m/seed, what is the value over just writing m/seed? Yes, this was just to have and equivalent for RxJava just no need in particular. I wrote those functions, only to learn and play with Missionary. They will only live in this gist 😀

kawas16:07:31

I understand the choice of leonoel to keep helpers out of the core lib. RxJava do have a lot of methods and many are missing 🙁