cljfx

https://github.com/cljfx/cljfx
pbaille 2021-03-20T09:35:44.002800Z

"a little nervous about the JVM" 😄

pbaille 2021-03-20T10:09:14.009600Z

I'm starting to build an app with cljfx, I was a little nervous too at the beginning (being used to the web for UIs) but the more I'm reading the docs, examples and the code, the more I like it. Escaping from clojurescript is quite nice, don't be reluctant to use macros or clojureJVM's spécific constructs is quite liberating. One thing that I don't really get is how I'm supposed to use contexts. As far as I understand for now, every view function can receive the whole context as part of the description, and we can use fx/sub-val to build the data that our view is needing, it is nice, but I'm wondering if it would be even nicer to decouple those to things. Thinking about this I was wondering if it would be a decent practice to create a sub-context like this: (-> whole-context (fx/sub-val f) fx/create-context) And passing it into the view function instead of the whole app context. Doing this seems to allow to be able to plug views into different contexts without modifying the view function itself. One nice thing I think would be to be able to define UI components that are context agnostics by letting the user specifying how the component plugs into the host app context. Some analog reflexions could be done about events and effects I think. One other thing that intrigues me is coeffects in the example 18. In re-frame, I believe, coeffects are attached to particular events at registration time, here coeffects seems to be global (computed for every event). Of course, tackling those concerns is possible with the current implementation of cljfx which is surprisingly simple and flexible ! But I'm curious to know what you think of those ideas. Have a nice week end.

❤️ 1
vlaaad 2021-03-20T11:53:21.012Z

The purpose of contexts is to pass the whole state to every component, if you want decoupling you can pass the minimum amount of data as arguments. Contexts = easy yet complex, arguments = simple and sometimes easy, sometimes hard.

vlaaad 2021-03-20T11:55:00.013500Z

I did contexts because I had a lot of positive experience with re-frame that uses similar model. I made all that stuff (contexts, effects, co-effects) optional because I don't have a strong opinion that this is a one true way to do UI app development

vlaaad 2021-03-20T11:59:05.016300Z

I built Reveal on cljfx and it does not use contexts, effects and co-effects, instead the whole app state is flowing through arguments, and event handling is done differently: every event handler has to return a function that will be used to swap! the current app state. I think this approach is better than deref in co-effect + reset in effect since it's atomic.

vlaaad 2021-03-20T12:02:37.018700Z

Although, one thing I did to make stuff easy in Reveal is I built a horrible hack to support "local mutable state" that can read and write in a state map using a special lifecycle. Horrible, but very useful.

pbaille 2021-03-20T16:51:01.023400Z

Thanks for the clarification, this idea of returning a swap function from the event-handler is interesting ! I think that for handling global mutable state it is nicer than deref+reset indead. But maybe for other "effects" like database read-write, re-frame approach would be preferable.

pbaille 2021-03-20T16:52:32.024700Z

I neither have a strong opinion on UI app dev. I like re-frame too, but sometimes I find it a little overkill.

pbaille 2021-03-20T16:53:32.025700Z

I'm curious about what yields you to need local mutable state in Reveal.

vlaaad 2021-03-20T16:58:28.026Z

Other "effects" are executed directly in event handlers :P

1