Push-based is an interesting choice here. I've built a couple push based reactive libraries myself, and they have some downsides which the authors don't seem to address.
Push often leads to wasted computations via updated values that don't end up getting used downstream either due to later updates affecting the same downstream nodes or simply because a value isn't being actively observed. Batching changes to signals can avoid the first cause (and it seems their execution model is implicitly batched by default?), but it doesn't solve the second.
Push-Pull systems (which don't seem to be mentioned) solve this by pushing invalidation of signals down the graph, then on pull any signal that is invalid gets recomputed. Handling cycles in the reactive graph is also easier with this approach, rather than getting stuck in an infinite update loop, if something is invalidated it's consumers do not need to be invalidated again.
I think the effort of creating RP languages is definitely a worth-while endeavor, but I'm not sure that they should have no imperative code, as seen with the recursive example taking things to the imperative or functional code level can have benefits. It would be interesting to see a language that is by default reactive, but has an escape hatch for imperative/functional logic.
Function free but then signals are basically functions.
It's like saying that a free monad represents a computation but doesn't actually execute it.
The user can read the context and execute computations and side effects.
From a DX point of view it can enable some good applications but it just shifts "where" the computation will run. The developer will still think in terms of functions.
I'm a fan of languages that don't try to be all things to all people, but instead focus on doing one thing very well.
(I also love Perl, so I'm not the most consistent person, but I love it most for its focus on text handling, so I'm not the most inconsistent person either.)
Imperative languages that have bolted on functional features, e.g., don't give you the guarantees (constraints) that FP languages can offer. And of course in OO languages state is everywhere.
I like this feature quite a bit:
> We propose a different approach that makes mutable state an explicit part of the language model. In Haai, deployments are able to accumulate state by means of so-called trampoline variables — or trampolines for short. They provide programmers with a general notion of state in the RP model. In essence, a trampoline is a variable, local to each deployment, that is updated after each turn.
this discusses the development of a new reactive programming language designed to exclusively handle reactive programming without the complications of mixing reactive and non-reactive code, common in Embedded Domain Specific Languages (EDSLs). By avoiding traditional functions and the problematic mechanism of lifting, this language aims to offer a simpler, more reliable approach to reactive programming. It introduces features like stateful reactors, signals with dynamic dependencies, and recursively-defined reactors, aiming to enhance the comprehension and implementation of reactive programming for both language designers and users.
There's also https://github.com/mech-lang/mech which is a sort of descendant of Eve https://witheve.com/ . That too seems to be getting close to hiatus. It's a bit of a shame since it seems like quite a nice paradigm for some stuff like GUIs, interactive stuff, and discrete event simulation, but I suppose the paradigm is both a bit obscure and different enough from everything else that it becomes a "boil the ocean" situation where one or a few people try and hack away but aren't really able to get much traction and eventually tired themselves out.
With appropriate types and behaviors and a runtime in some other language with normal functions, you could make the code you see that "looks a lot like functions" do what this language aims to do (reactive programming -- when an input changes, update the output). The key is in what these new concepts _can't_ do. They _only_ update in response to input changes. There is no part of the language that isn't intimately tied to the reactive scheduler.
Why would you want that? The paper is pretty readable, but it's (1) interesting theoretically and (2) it solves a lot of failure modes in reactive programs, such as deadlocking a single execution thread, never yielding back to the scheduler, ....
probably not - 'monads' are an interface (typeclass in haskell) for which specific functions (bind, unit) need to be defined. you can do monadic programming in any language, including python. that is, functions are central to the implementation and use of monads, so being 'function-free' seems contrary.
Push often leads to wasted computations via updated values that don't end up getting used downstream either due to later updates affecting the same downstream nodes or simply because a value isn't being actively observed. Batching changes to signals can avoid the first cause (and it seems their execution model is implicitly batched by default?), but it doesn't solve the second.
Push-Pull systems (which don't seem to be mentioned) solve this by pushing invalidation of signals down the graph, then on pull any signal that is invalid gets recomputed. Handling cycles in the reactive graph is also easier with this approach, rather than getting stuck in an infinite update loop, if something is invalidated it's consumers do not need to be invalidated again.
I think the effort of creating RP languages is definitely a worth-while endeavor, but I'm not sure that they should have no imperative code, as seen with the recursive example taking things to the imperative or functional code level can have benefits. It would be interesting to see a language that is by default reactive, but has an escape hatch for imperative/functional logic.