I'm almost starting to regret not picking Clojurescript for my app
I'm almost starting to regret not picking Clojurescript for my app
The ClojureScript community obviously didn't come up with everything, many of the ideas are very old ideas for UI development but didn't really exist in the "web-sphere" before. I'm pretty sure I can remember Dan Abramov saying Redux was directly inspired by stuff happening in the ClojureScript community, particularly around atoms and hot-reloading. Also I think Pete Hunt mentioned stuff David Nolen was working on when talking about React as well initially, but less confident about this.
See https://redux.js.org/understanding/history-and-design/prior-... which lists Elm right under Flux.
Now we just have to get a handle on all the leaky stuff at the edges of every “functional core”, because there lay many dragons.
In my experience, languages like C, Go, Java, C# still dominate the backend. Replacing JavaScript is such a simple and well-defined task that I expect it will be completed much sooner. Maybe only a decade or two.
My gut is telling me erlang might have tackled this.
Think of how we do it on the wire: we send a description of a event (command/effect) to an API server which routes/dispatches it to something that applies an effect. It’s not a function call, but a generic (implementation agnostic) description of intent in pure data.
It’s like that but inside your program.
Just a function.
> where it's sending that once it's created, and then where the "drivers" would come from and how they would get invoked
Depends on entirely on how you'd do it.
You can apply the Functional Core Imperative Shell architecture, where side-effecting, stateful code (imperative shell) always calls the functional code (functional core). The shell basically handles files, db connections, HTTP/TCP, exceptions, retries etc. and basically asks the functional core of what to do by providing the data that comes out of those things.
For example there's no reason a HTTP routing library has to do IoC. It can also be structured in a way so you you give it a path and it returns you data, such as an event description, a set of questions or a command description etc.
There are also frameworks that work this way, for example the UI state management framework re-frame. It handles the side effects for you and calls your functions that you register on certain UI events. The re-frame documentation is very good at explaining this step by step.
(rf/reg-event-fx
:stop-timer
(fn [{:keys [db]} _]
(let [handle (db :ticker-handle)]
{:db (assoc db :ticker-handle nil)
:stop-ticker [handle]})))
The side effect here is to a stop a running ticker on the page, but the `reg-event-fx` function just returns a map (data) where the first key is :db (which is the new app state, which is like a db, can even have a sorta schema over it) and the second key is the actual even :stop-ticker, which takes an argument handle (the handle of the ticker to stop).The event handler is just describing the side effect that is to occur by returning the map.
Sorry, I know no clojurescript, so I'm having a hard time parsing it even googling the syntax
There is a piece of code which emits the event :stop-timer, that stops a js timer in the window.
:on-click (fn [_](rf/dispatch-sync [:stop-timer]))
In clojure a map has the syntax {:key :value}
So this event handler is returning a map which describes the event.There is then a further function which does the actual event
(rf/reg-fx
:stop-ticker
(fn [[handle]]
(when (not (nil? handle))
(js/clearInterval handle))))
BUt as far as testing goes, you can test the event handler and test that it returns the expected map. The framework is responsible for actually executing the event that is described the event handler and it does it via the name :stop-ticker. Your event handler itself can remain a pure function.Personally I'm not a fan of this abstraction (another layer of indirection). I'd rather take a `transact` function as an argument.
It's a bit of a tragedy it has been mostly abandoned. I wish a Lisp, such as Clojure, emulated Mozart/Oz semantics.
There's also a summary poster [2].
Actually, CTM was in Rich Hickey's reading list when he designed Clojure [3].
[1] https://www.info.ucl.ac.be/~pvr/book.html
[2] https://www.info.ucl.ac.be/~pvr/paradigmsDIAGRAMeng201.pdf
[3] https://www.goodreads.com/list/show/137472.Rich_Hickey_s_Clo...
Agreed. But wow the documentation was a mess. So much language progress these last decades has been around increasing minimum expectations for ecosystem.
Poplog (integrated CommonLisp, prolog, ML, an a C-like; 1980's) is another on my list of roads regrettably not taken. Killed by commercialization. Which also zombied CL.
https://github.com/hebisch/poplog https://www.cs.bham.ac.uk/research/projects/poplog/freepoplo...
> Of course, many of these paradigms are useless in practice, such as the empty paradigm (no concepts)[1] or paradigms with only one concept.
> [1]: Similar reasoning explains why Baskin-Robbins has exactly 31 flavors of ice cream. We postulate that they have only 5 flavors, which gives 2^5 − 1 = 31 combinations with at least one flavor. The 32nd combination is the empty flavor. The taste of the empty flavor is an open research question.
But the rewards are in line with the risks.