Skip to content
Kenneth Tilton edited this page Jan 29, 2024 · 14 revisions

Welcome to the Flutter/MX Wiki

Flutter/MX applies the Matrix reactive library to Flutter, a Dart GUI, with ClojureDart as the implementation language. Gasp. Let us break all that down.

Flutter

The Flutter GUI is written in Google Dart, a "client-optimized language for developing fast apps on any platform". By "any" they mean Web, mobile (iOS or Android), and even Win32, Cocoa, or UNIX desktops. Parenthetically, Dart is statically typed and object-oriented, and Flutter, we will see, takes a novel Lego blocks approach to composing an interface.

ClojureDart

ClojureDart is a port of Clojure to Dart, and comes with substantial Flutter support. That support includes dozens of self-contained example apps implemented using cljd.flutter macrology to make Flutter more approachable. Looking ahead a bit, widgets implemented using cljd.flutter may be included as sub-components in an f/mx component, but not the other way around.

The win here is Clojure's Lisp-y dynamism, including dynamic typing, and the flexible map data structure.

Matrix

Inverted tree Matrix adds a deep reactive/declarative paradigm to our mix, and more. Matrix breaks the mold of today's GUI frameworks in several ways:

  • no Flux/Redux/Vuex secondary store: GUI state is managed "in place", so there is no artificial secondary schema to work around, and none of the concomitant boilerplate. The GUI application is the GUI schema;
  • "point" reactivity: All reactivity happens at the level of the instance property. Any property of an instance can be declared as the function of, or formula over, any properties of the same or other instances. Or properties can instead be declared to be so-called "inputs", mutable by imperative code, say, in an event handler. It cannot be formulae all the way down.
  • no publish/subscribe: a formulaic property's dependencies are detected automatically at run time, when the formula simply reads another property, so there is no need to "subscribe" explicitly. Likewise, any change to a property gets propagated automatically to any dependent properties (without glitches), so there is no need to "publish" explicitly;
  • unfettered scope: Any property formula can "see" any property of any other instance in the application. (Inadvertent cycles are detected at run time and an exception thrown.) Likewise, imperative code can reach and update any "input" instance property;
  • the prototype object paradigm: any instance can be authored with custom properties as needed to track application state. This is how Matrix apps avoid the disconnect of a secondary store. Again, a Matrix GUI app is its own store.
  • universal reactivity: all interesting program state can be made reactive. When dealing with any non-reactive subsystem, we can write more or less straightforward "glue" code to make it reactive. (Flutter itself was a much less straightforward gluing exercise!) We will be happy to assist with this wrapping process, especially for commonly required libraries.

Proof of concept?

This is just a proof of concept release, with little documentation and the Flutter API only partly exposed. Please contact its author for enthusiastic support: DM @kennytilton on the Clojurians or FlutterDev Slacks and I will be happy to pair with you to get you rolling.