• Stars
    star
    178
  • Rank 214,989 (Top 5 %)
  • Language
    HTML
  • License
    MIT License
  • Created almost 7 years ago
  • Updated 10 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Fine-grained, transparent data flow between generative objects.

Matrix cell culture

Welcome to the "mono" repo for Matrix, a generic, fine-grained, reactive engine that began as Common Lisp Cells twenty-five years ago.

Of most interest to many will be the application of Matrix to Web and mobile app development, and now ClojureDart/Flutter UI development. We were actively documenting the Web solution in a new mxWeb Training app/tutorial when ClojureDart came along.

Flutter/MX, implemented with ClojureDart, has successfully reached the proof-of-concept stage. Next up is sufficient documentation of Matrix to support those interested in exploring Flutter/MX or any Matrix-wrapped front end.

This repo contains:

  • Clojure/ClJS version here;
  • a JavaScript version here;
  • wrappers at various stages of development for HTML/CSS, ReactJS, and ReactNative; and
  • wrappers for XHR and localStorage, with more to come.

Here is our road map, absent requests for specific implementations for evaluation/adoption:

  • Matrix overview
  • a hands-on, progressive Flutter/MX learning experience, linking to...
  • ...reference-style documentation as needed and...
  • ...new clojure.test content serving also to demonstrate advanced Matrix features;
  • the same ^^^ for mxWeb;
  • the same ^^^ for Javascript;
  • the same for CLJS ReactNative.

Some new/recommended content:

Watch this space for frequent updates, or contact me directly: kentilton at gmail dot com.

Matrix from 30,000 feet

With the Matrix library, global variables or individual properties of objects can be expressed as so-called cells. Cells come in two flavors. Formulaic cells use standard HLL code to compute their value from other cells. For a dead simple example, the TodoMVC rules mandate we apply the "completed" class to to-do LIs if and only if the user has marked them as, well, completed:

  (li {:class   (c? (when (<mget todo :completed)
                        "completed"))
       ...}...)

Above we see the CSS class tracking the completed property of the lexically closed-over todo, another Matrix-aware object lifted from window.localStorage. (mget <x> <y>) establishes dependency of the enclosing formula on property y of x. Not shown: a so-called observer (discussed below) automatically propagates freshly computed values of class to the actual DOM.

Input cells are assigned new values by conventional imperative code, usually in an event handler.

(input {:class "toggle" ::tag/type "checkbox"
        :checked (c? (<mget todo :completed))
        :onclick #(mswap! todo :completed)}) ;; <-- mswap!> does the swap and then triggers dataflow to dependents

mswap! is a dataflow "writer" that mirrors mget. It causes all direct or indirect dependents to recalculate. (Note also the checked attribute, another example of a property following the completed property of our todo.)

Why the "input" characterization? It cannot be rules all the way down. These cells are the inputs into the dataflow from outside imperative code. The diagram below is of a directed acyclic graph depicting the flow that arises when input cells change and their new values are consumed by formulaic cells (when their recomputation is triggered). In the diagram below, cells 7, 5, and 3 would be the input cells.

DAG graphic

The dataflow engine propagates each new input value by recursively recomputing dependent formulaic cells in a glitch-free cascade. We get useful behavior out of this cascading calculation via "on change" callbacks. We name these callbacks "observers" (not to be confused with RxJS or MobX observables). Much simplified:

(defmethod observe-by-type [:tiltontec.tag.html/tag] [slot me new-value prior-value _]
  (case slot
        :hidden (set! (.-hidden dom) new-value)
        :class (classlist/set dom new-value)
        :checked (set! (.-checked (tag-dom me)) new-value
        ....)))

In contrast with RxJS and MobX, Matrix observers work off to the side, if you will, as ancillary participants tapping into the main flow to produce tangible behavior. Think "UN observer vs. combatant".

We refer to the combination of cascading recomputation and consequent observation as dataflow. Objects with Cells as properties are called models in the sense of a working model, this because these objects change and act autonomously as driven by dataflow. Hence the md- prefix, by the way.

Matrix includes support for arranging models as a tree in which a model can have zero or more children and children have one parent and have a reference to that parent. This omni-directional linkage means any cell formula or observer can reach any other cell in the tree of models; they have perfect information. We call a population of objects connected by interdependent cell properties a matrix in concordance with this definition (forget the otherwise fine movie):

ma·trix ˈmātriks noun an environment in which something else takes form. Origin: Latin, female animal used for breeding, parent plant, from matr-, mater

In the case of TodoFRP, that something else is an interactive do-list.

A major design goal was ease of use by programmers. Dependencies are established transparently by simply reading a property. Dataflow is triggered simply by assigning a new value to an input cell. Shuffle the code during a refactoring and the pub/sub moves with it.

More Repositories

1

cells

A Common Lisp implementation of the dataflow programming paradigm
Common Lisp
211
star
2

flutter-mx

Flutter + ClojureDart, with Matrix Inside(tm)
Clojure
125
star
3

qooxlisp

The Last Web App Framework You Will Ever Evaluate: qooxdoo, Lisp, and Cells
JavaScript
46
star
4

whoshiring

A browser for Hacker News's Ask HN: Who's Hiring, with Matrix Inside(tm)
JavaScript
28
star
5

web-mx

A Web Un-Framework, with fine-grained, transparent reactivity all the way down.
Clojure
27
star
6

mxtodomvc

The TodoMVC Classic implemented with mxWeb and Matrix
Clojure
24
star
7

rube

A pure dataflow aka reactive library for building Clojure or ClojureScript models that run by themselves (like Rube Goldberg Machines). Includes Qxia, a mobile app development framewor based on qooxdoo mobile.
JavaScript
22
star
8

its-alive

A Clojure dataflow library for building application models that run by themselves. It's alive!(tm) Starting out as a literal translation of my Common Lisp Cells library.
Common Lisp
21
star
9

utils-kt

Generic hacks used in any project
Common Lisp
15
star
10

celtk

A Common Lisp wrapper of Tcl/Tk, with Cells Inside(tm)
Common Lisp
13
star
11

kennytilton.github.io

Currently just the home for live demos of JS and CLJS variants of sundry Matrix toy apps.
HTML
12
star
12

Cello

A Cells Inside(tm) desktop UI framework rendered by OpenGL
Tcl
9
star
13

MatrixJS

Lightweight yet powerful JS and CLJS frameworks united by a custom dataflow/reactive hack.
JavaScript
8
star
14

SimpleJX

A Web un-framework as simple as HTML with reactive power all the way down.
Clojure
4
star
15

mxweb

The web application un-framework for the Matrix (dataflow library)
Clojure
4
star
16

flutter-mx-sandbox

Flutter/MX examples
Clojure
4
star
17

gui-geometry

Generic layout widget with the same nested thinking as OpenGL
Common Lisp
4
star
18

flutter-mx-starter

A skeleton repo with a sample ClojureDart + Flutter/MX sample app, to help you build your own.
Clojure
4
star
19

kt-opengl

Kenny's rough, incomplete, unfancy OpenGL CFFI bindings because he cannot abide cl-opengl
Common Lisp
4
star
20

cffi-extender

A few tricks to facilitate converting a C header file into CFFI definitions.
Common Lisp
3
star
21

peoplesort

A people database manager app.
Clojure
2
star
22

mxweb-trainer

A learn-by-doing project for Matrix and mxWeb
Clojure
2
star
23

ciWeb

A pure JS web application framework thinly wrapping HTML and CSS, with Cells Inside(tm)
JavaScript
2
star
24

hiringagent

The latest, greatest version of the ClojureScript Reagent version of my AskHN Who's Hiring browser
HTML
2
star
25

learning-datomic

Join me as I learn Datomic by writing code and seeing what happens.
Clojure
2
star
26

qxia

A Clojurescript qooxdoo wrapper with Cells Inside(tm)
JavaScript
2
star
27

cells-npm

Transparent reactive state manager for JS via NPM/Node.js
JavaScript
1
star
28

model-npm

Reactive models for Node
JavaScript
1
star
29

web-mx-workshop

Where one can learn how to Web/MX by following the evolution of Web/MX-based projects.
Clojure
1
star
30

todomx

The TodoMVC Classic implemented with the Matrix (JS and CLJS dataflow projects)
HTML
1
star
31

web-mx-sampler

Web/MX samples and examples under one repo
Clojure
1
star
32

concurtimes

Printing text from five sources in side-by-side columns nicely.
Clojure
1
star
33

spammer

Proof-of-concept full stack CLJS mxWeb front-end and CLJ Matrix+Ring back end wrapping a REST API. Gasp.
Clojure
1
star