@hiskennyness I am absolutely sure that it is fast to start using Matrix when one makes the decision to use it. I believe the true issue is somewhere else: Trust that one small guy achieve to make an amazing library that works. Issues typically arise in the mid/end stage of a project, once one has to deal with the edge cases of a library. And also, every additional library is something that one day could stop working (say no longer working with a new version of Java, or Clojurescript Compiler, or whatever. And it is something that could lead to problems with other libraries. Or it becomes a security risk (becase one of the library dependencies have an vulnarability.
Well, as a Common Lisper and now a Clojurian, I am accustomed to folks not using great tools. Indeed, before adopting CL I spend months ignoring MCL adds in the APDA catalogs, because I "knew" it was not "real world". sigh
"Trust that one small guy achieve to make an amazing library that works." Given what we see from the twenty thousand big guys at Microsoft....anyway, the good news is that Matrix is thirty years old and runs this http://tiltonsalgebra.com/# inter alia. And it is open source. What could go wrong! 🤣 Oh, right, the integration with Mission. That actually scares me. :) Good luck with your project!
I know that. I just imagine that you are frustrated that not a lot of people are using Matrix. So I wrote what I think is the reason for this.
For a ui project, also the issue is how to gradually integrate missionary.
Clojure is a niche community, but there is a lot of innovation going on. I find it surprising that there are only 3 clojure libraries that focus on dynamically updating the dom in a purely Clojurescript way: 1. Matrix 2. Hyperfiddle Electric 3. MrClean (a 300 lines library that implements reagent api without react). Thats all there is. All the rest wrap something else.
Now there is #replicant too
The thing that keeps me thinking is how the structure of my apps would change with Matrix. And so far I think it would be similar to Reframe. The diffeence being that reframe only has one global db, and matrix can have multiple. Reframe has event-handlers defined independent, and shields everthing from the developer. Matrix gives an api that allows to do things more direct.
I had to write bridges/adapters so I can use core.async / promises / manifold streams in one app. This are all event based systems in essence.
I wonder if there is something similar that might be needed for Matrix at some time.
But perhaps Matrix core is the DAG (or the model) of the individual cells, which always have to be defined, so that they can be rendered in the DOM. There is no choice NOT to RENDER. If you are on a webpage, you are on the webpage.
So perhaps building stuff with Matrix does not require such adapters.
I still havent made my mind up on this.
Perhaps similar to how Tonskys RUM allows to have different reactive sources (that in RUMs case drive react app).
Datascript can be used as a db in the browser that is a reactive source. There is a reframe fork that works on Datascript. Datahike is working on reactive version of Datahike in the browser.
So might be that Datascript/Datahike/normalAtoms/Matrix need to be integrated somehow together.
I am sorry I only write from a Browser UI perspective. I know Matrix has a lot more. But that is not of interest to me / not my speciality, so cannot incorporate that elvments.
re-frame is Flux, the anithesis of Matrix, which automatically builds what any Flux forces the developer to maintain with explicit boilerplate. I have written on that somewhere, Medium I think, and in various repo docs.
hahah
Yes, the HOW is the antithesis.
But keeping state separate from UI is what is the same.
That Algebra app transparently maintains state in Postgres, where persistence matters. But that is all in Common Lisp.
"But keeping state separate from UI is what is the same." Not at all. Matrix handles state "in place". So the color property of the style attribute of a DOM element has its own formula. mxWeb takes care of propagating that to the actual DOM style.
And please forgive me if some things I say about Matrix are not 100% correct. My talent is to see something that is excellent, and Matrix is excellent for sure. All the little details I only pick up after using it for a while on a real project.
The programmer experience of "in place" state management rocks the casbah, if you wiill.
(reset! matrix (make rxApp ;; load all to-dos into a depend-able list.... :rxs (rx-list) ;; build the matrix dom once. From here on, all DOM changes are ;; made incrementally by Tag library watchs... :mx-dom (cFonce (with-par me (landing-page))) ;; the spec wants the route persisted for some reason.... :route (cF+n [:watch (fn-watch ;; fn-watch convenience macro provides handy local vars.... (when-not (= unbound old) (io-upsert "rx-matrixcljs.route" new)))] (or (io-read "rx-matrixcljs.route") "All")) :router-starter start-router)))
Do this code is not the global state,
it is just basically the page router component.
Yeah, forget the router. The root MX object includes what I call MX proxies for real UI objects. But these proxies get echoed directly to the DOM, so they seem like the UI elements. So any UI state is actually maintained in the MX incarnation, along with other app state such as active Todos. This is not what reframe does.
Yeah, I have consulted on many a re-frame project. Not the end of the world. But it adds a quite thick cognitive layer for what could be handled by a suitably aggressive library. Facebook just missed the alternative to a separate "app DB".
Btw, "in place" vs app DB is not a little detail. But I can see how it might not jump out at someone who has not programmed both Flux and MX>
I have used reframe a lot for a few years. One problem that I ran into, is that after a few years, it became very hard to remove event handlers. This is because there is DevTooling that helps to find where a function is being used.
The other problem with reframe I had is that it became difficult to see hwo the flow of effects is. So I had to read 5 eventhandler functions (that are perhaps in two different projects) to find out how the flow of event goes.
And I that was for the happy path. It was sort of impossible to know I dealt with all the things that could go wrong at all places correctly.
The thing I like about reframe is that is easy to wire different components together. Since there is no passing of props of parent to child, you just go to the db and there it is what you need.
And one thing that kept making problems is that one eventhandler would fuck up the db; perhaps the code of someone else. And then my own code would also stop working. But this I fixed at some point with a few interceptors.