{"id":13568488,"url":"https://github.com/leonoel/missionary","last_synced_at":"2025-05-14T06:14:30.358Z","repository":{"id":41284353,"uuid":"135820305","full_name":"leonoel/missionary","owner":"leonoel","description":"A functional effect and streaming system for Clojure/Script","archived":false,"fork":false,"pushed_at":"2025-03-06T19:51:50.000Z","size":541,"stargazers_count":725,"open_issues_count":49,"forks_count":29,"subscribers_count":27,"default_branch":"master","last_synced_at":"2025-04-03T02:05:09.703Z","etag":null,"topics":["clojure","clojurescript","reactive-streams"],"latest_commit_sha":null,"homepage":"","language":"Clojure","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"epl-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/leonoel.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-06-02T13:33:14.000Z","updated_at":"2025-03-30T15:30:08.000Z","dependencies_parsed_at":"2022-07-06T11:21:03.300Z","dependency_job_id":"2e7212cf-9579-4ff2-ac0e-040bbddc1796","html_url":"https://github.com/leonoel/missionary","commit_stats":{"total_commits":247,"total_committers":7,"mean_commits":"35.285714285714285","dds":0.3157894736842105,"last_synced_commit":"be0f782a9322f78c31bb729359f40841de427a84"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leonoel%2Fmissionary","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leonoel%2Fmissionary/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leonoel%2Fmissionary/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leonoel%2Fmissionary/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/leonoel","download_url":"https://codeload.github.com/leonoel/missionary/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248154965,"owners_count":21056541,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["clojure","clojurescript","reactive-streams"],"created_at":"2024-08-01T14:00:26.542Z","updated_at":"2025-04-10T03:42:12.595Z","avatar_url":"https://github.com/leonoel.png","language":"Clojure","funding_links":[],"categories":["Clojure","Awesome macros usage","Java"],"sub_categories":[],"readme":"# Missionary – a functional effect and streaming system for Clojure/Script\n\nMissionary is a reactive dataflow programming toolkit providing referentially transparent operators for lazy continuous signals, eager discrete streams, and IO actions. Missionary aims to improve over state-of-the-art reactive systems, it can be used as a general-purpose asynchronous programming toolkit but also as a basis for event streaming and incremental computations.\n\n```clojure \n(require '[missionary.core :as m])\n\n(def !input (atom 1))\n(def main                                      ; this is a reactive computation, the println reacts to input changes\n  (let [\u003cx (m/signal (m/watch !input))         ; continuous signal reflecting atom state\n        \u003cy (m/signal (m/latest + \u003cx \u003cx))]      ; derived computation, diamond shape\n    (m/reduce (fn [_ x] (prn x)) nil \u003cy)))     ; discrete effect performed on successive values\n\n(def dispose!\n  (main\n    #(prn ::success %)\n    #(prn ::crash %)))                         ; prints 2\n(swap! !input inc)                             ; prints 4\n                                               ; Each change on the input propagates atomically through the graph.\n                                               ; 3 is an inconsistent state and is therefore not computed.\n\n(dispose!)                                     ; cleanup, deregisters the atom watch\n```\n\nFeatures\n* Discrete event streams with backpressure\n* Continuous-time signals with lazy sampling\n* Correct incremental maintenance of dynamic DAGs without inconsistent states (aka FRP glitches)\n* Correct error handling by default. Strict process supervision provides transparent propagation of cancellation and failure, with strong resource cleanup guarantees\n* Asynchronous design for efficiency and ClojureScript compatibility\n* Reactive Streams compliant\n\nKey ideas\n* Unification of functional effect systems and FRP / dataflow programming\n* Unification of continuous-time and discrete-time primitives under the common Flow protocol\n* Embrace and reuse Clojure core abstractions including collections, transducers, reducing functions and reference types\n* Sequential composition DSL is a superset of clojure with full metaprogramming support, same expressive power as monads\n\nMissionary's mission is to establish a rigorous foundation for modern web programming, particularly sophisticated real-time collaborative applications. Missionary's reactive primitives are fully separated and unbundled in order to achieve low-level control over every aspect of the computation (discrete vs continuous, eager vs lazy, allocation and reaction boundaries).\n\nMissionary can be used as a foundation to build higher level reactive abstractions. For example, Missionary's \"reactive VM\" is the compiler target of [hyperfiddle/electric](https://github.com/hyperfiddle/electric), a reactive dialect of Clojure/Script for UI programming.\n\n# Dependency\n\nProject maturity: experimental, but stable. The current development priority is documentation.\n\n```clojure\n{:deps {missionary/missionary {:mvn/version \"b.44\"}}} \n```\n[![clojars](https://img.shields.io/clojars/v/missionary.svg)](https://clojars.org/missionary)\n[![cljdoc](https://cljdoc.org/badge/missionary/missionary)](https://cljdoc.org/d/missionary/missionary/CURRENT)\n[![build](https://api.travis-ci.com/leonoel/missionary.svg?branch=master)](https://app.travis-ci.com/github/leonoel/missionary)\n[![license](https://img.shields.io/github/license/leonoel/missionary.svg)](LICENSE)\n\n# Prior art\n\n### vs imperative\n`missionary` promotes a functional approach to concurrency, focusing on computation instead of conveyance. It is deeply\nimpacting for the user because the objects implied in both cases have fundamentally different requirements : whereas\ncommunication devices have indefinite scope and can be safely garbage collected, running processes are bounded in time\nand must be supervised.\n\nPopular conveyance-oriented techniques include clojure's succession model, CSP, futures/promises, actor systems. In\nall of these programming models, the first-class primitive is a communication device (resp. reference types, channels,\ndataflow variables, mailing addresses) used as an interface to coordinate encapsulated stateful processes. This low-level\nprogramming style generally makes no attempt to provide any structure to concurrent computations, which means\nsupervision must be implemented in user space, generally as an afterthought, often simply omitted. Imperative\n[structured concurrency](https://en.wikipedia.org/wiki/Structured_concurrency) is currently an active area of research.\n\nFunctional composition is fundamentally more constrained because it enforces a strict hierarchy of concurrent programs.\nThe benefit for the user is that supervision concerns don't leak to the domain, the runtime engine knows about the\nprogram structure and therefore can endorse the right behavior in face of failure (cancel siblings and propagate error\nto parent). Usual communication devices are still provided to cover use cases requiring data transfer across branches\nof the supervision tree, but their usage is specialized instead of generalized.\n\n### vs functional\n[ReactiveX](http://reactivex.io) is one of the first functional effect system to have gained significant traction\nin mainstream languages. Other popular incarnations of this paradigm can be found in the Scala ecosystem, namely\n[Cats Effects](https://typelevel.org/cats-effect), [ZIO](https://zio.dev) and [Monix](https://monix.io), all heavily\ninfluenced by haskell's IO monad.\n\n`missionary` aims to make sequential composition more practical, dismissing monadic binding in favor of a DSL that is\na superset of the host language. This idea is by no means new, it is even rather popular nowadays and present in almost\nevery modern concurrency framework, including in clojure with [core.async](https://github.com/clojure/core.async)'s\n`go` blocks. Ambiguous expressions are the natural extension of this technique to multiple value producers, but that\npart has definitely not reached mainstream yet. Surprisingly enough, it is sparingly used even in the modern functional\nprogramming landscape.\n\n### vs reactive\nWhile traditional streaming engines are focusing on discrete events, `missionary` is designed upfront to also support\ncontinuous time, which is the realm of [FRP](https://en.wikipedia.org/wiki/Functional_reactive_programming). This is\nmade possible by the flow abstraction, a foundational protocol allowing a producer to signal availability of a value\nwithout eagerly computing it, making suitable for both backpressured event streaming and lazy sampling of time-varying\nvalues. This unified representation bridges the gap between functional and reactive programming into a consistent model\nproviding the best of both worlds.\n\n## Documentation\n\nAPI Reference: [`missionary.core`](https://cljdoc.org/d/missionary/missionary/CURRENT/api/missionary.core)\n\nQuickstart repo: [quickstart.cljs](https://github.com/dustingetz/missionary-quickstart/blob/main/src/quickstart.cljs) (clone repo and jack in)\n\nDiscussions:\n* [ClojureVerse (2019)](https://clojureverse.org/t/missionary-new-release-with-streaming-support-design-notes/4510)\n* [reddit (2021)](https://www.reddit.com/r/Clojure/comments/k2db8k/leonoelmissionary_a_functional_effect_and/)\n\nTutorials\n1. [Hello task](doc/tutorials/hello_task.md)\n2. [Hello flow](doc/tutorials/hello_flow.md)\n3. [Comparison to RxJava](doc/tutorials/rx_comparison.md)\n\nHow-to guides: [cookbook](https://github.com/leonoel/missionary/wiki)\n\nExplanations\n* [re:Clojure 2021](https://www.youtube.com/watch?v=tV-DoiGdUIo)\n\n## Community\n\n[#missionary](https://app.slack.com/client/T03RZGPFR/CL85MBPEF) on Clojurians slack\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fleonoel%2Fmissionary","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fleonoel%2Fmissionary","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fleonoel%2Fmissionary/lists"}