Does clojure(script) have its own framework for functional event streams?

Composable functional event streams are called reactive programming by RxJS and RxJava.
Functional event streams can be composed together with functions like zip, filter, map, etc, …

Some people call reactive programming functional reactive programming.

To be precise, functional reactive programming adds time to composable streams. Functional reactive programming is functional event streams of “time-varying” values. Event streams don’t have to contain time of event. Haskell’s reflex framework offers functional event streams of time-varying values.

RxJS and RxJava bring functional event streams to clojure(script), but I wonder whether clojure(script) has its own framework for functional event streams.

You might enjoy core.async’s channels (GitHub - clojure/core.async: Facilities for async programming and communication in Clojure), which can be composed with core Clojure transducers for map, filter, and so forth.

1 Like

If you are searching for a framework help you development application frontend, I think re-frame is a good option. You don’t operate on event stream directly, instead you register functions as event handler and subscription handler.

If you want to build a event network or graph topology in Clojure(Script), core.async is a good option. It’s an implementation of CSP in Clojure(Script), you can use it in both frontend(in CLJS) and backend(in Clojure).

1 Like

missionary is an attempt to bridge the gap between functional effect/stream systems and reactive programming. It is reminiscent of RX but designed specifically for clojure(script) with a more expressive syntax, and improves the functional discrete streaming model with support for continuous time from the ground up and glitch-free propagation of events through dynamic DAGs.

4 Likes

Missionary is very close to haskell’s Reflex. Reflex has three main types

  • Event – discrete event at a point in time (streams). Eager, push-based
  • Behavior – continuous signal that can be sampled at any time t. Lazy, pull-based
  • Dynamic – a continuous signal (defined for all t) that also notifies when the value is updated. Push/pull – the notification that the signal has changed is is push, but computation itself is lazy, nothing is computed until you sample/pull.

http://docs.reflex-frp.org/en/latest/overview.html

Missionary has two flow types:

  • Discrete flow – analogous to reflex Event (eager push)
  • Continuous flow – analogous to reflex Dynamic (lazy pull, with push notification that something has changed)

I don’t think you need Reflex’s third type (Behavior pull without push notification), I don’t understand its value, missionary’s simplification seems to cover the same application functionality surface area with one fewer primitive.

2 Likes

Continuous vs discrete:

image

https://kefirjs.github.io/kefir/#about-observables

Kefir.js calls the two types “streams” (discrete) and “properties” (continuous). I believe Kefir is closer to missionary (continuous signals notify when a dependency has changed and thus the signal is ready to be sampled).

I should mention that at hyperfiddle we are working on a reactive dialect of clojure that compiles clojure syntax to missionary signals through a custom clojure analyzer. First teased on twitter two weeks ago. It can express incremental view maintenance of the dom (reactjs-equivalent but emits fine grained effects, no vdom). Since it’s reactive and natively async, it can also hop network, so streaming client/server datasync between incremental backend and incremental frontend falls out for free.

you don’t need a web framework, you need a web language

3 Likes

Is missionary compatible with clojurescript? It contains java code.

Yes, missionary works with Clojurescript.

1 Like

It has implementations for both clj and cljs, the feature set is identical minus thread interop. The JVM part is implemented in java because it’s a better fit than clojure for low-level code.