Yeah okay. Then why does nobody use it? Even languages like Elm ditched it for easier to understand concepts.<p>Let's face it. FRP kinda sucks. It's awkward as hell to use and takes way to many brain-cells to achieve simple results. Even the experts have trouble with it. I remember e-mailing the author of a popular FRP library once asking him how I could get multiple shapes moving on the screen at once (as opposed to just one). He replied that he had no idea. Apparently it was still an open problem he was working on. Yikes!<p>State turns out to be a convenient, natural way to represent... state. Funny, isn't it? That if you have some real world problem that involves state, that you want to model that using virtual state and not the high-order time-varying continuous functions that FRP uses. Even Alonso Church admitted that Turing's tape-based model of computation was easier to understand than his lambda calculus.<p>BTW one more thing. Spreadsheets are commonly cited as a good example of real-world FRP use. The great irony is that nobody on the planet thinks of spreadsheets as time-varying continuous functions. Nope. People view spreadsheets as a big grid of numbers... i.e. state.
Imagine you were trying to explain the temperature-conversion program's behavior in the simplest, clearest way possible. (That is, after all, what programmers fundamentally do: try to explain things to computers as simply and clearly as possible.) You'd probably say something like: "When the user changes the Celsius textbox, the computer changes the Fahrenheit textbox to the converted value." And indeed, that's the program most people would write:<p><pre><code> celsiusTextbox.whenChanged do
fahrenheitTextbox.value = cToF(celsiusTextbox.value)
end
</code></pre>
What you <i>wouldn't</i> say is something like: "The Fahrenheit textbox's value depends on whether the Fahrenheit textbox or the Celsius textbox was edited more recently. If the Fahrenheit textbox was edited more recently, its value is equal to the value the user entered into it most recently. If the Celsius textbox was edited more recently, the Fahrenheit textbox's value is equal to the converted value of the value the user entered into the Celsius textbox most recently." But that's the program you have to write in the "DCTP" approach proposed by the author.<p>I think this is true of a lot of UI programming: most people intuitively think about it in terms of "when X happens, do Y", so trying to cram it into another programming model is more trouble than it's worth.
What Steve calls "Denotative Continuous-Time Programming" – I think Clojurists call this declarative data programming – that is, you figure out a way to model the problem domain in data, and then write pure functions on that data. For example, React.js models the dom as data. Clojure gives you the toolkit of programming language primitives you need to do this easily, ergonomically and often, for all of your problem domains, not just virtual dom.<p>I think an example of database programming in "Continuous Time" would be<p><pre><code> (datomic.api/q '[:in $ :find ?e :where [?e :post/title]] db)
</code></pre>
where `db` is a time-pinned and consistent value of the database graph – in other words datomic.api/q is a conceptually pure function of time, time is a parameter, which implies you can rewind it or speculate into the future (both of which are supported by this interface)<p>As for abstracting HTTP – what if you considered network io as just a way to lazy load a cache of immutable database values? So for example, this would work a bit like Git – we don't care how the clone protocol works, just load me the file values I identified. Maybe it uses HTTP, maybe it uses something different, who cares? Get me the value I asked for in the fastest way possible given available infrastructure, distributed caches, etc.<p>Then, the question of IO resolves to: what categories of effects can be modeled as values and functions on values? Given declarative data programming in Clojure – basically anything!
Fascinating content. As someone burdened by working in a wildly non-denotative language (Python) but who would love to return to functional programming someday, the vision is very appealing.<p>I like FP because it allows me to be lazy; quoting the author:<p>> A denotative language resembles a dictionary or encyclopedia, where one can understand an entry by reading it and what it references. A non-denotative language resembles prose, like a novel, which you have to read cover-to-cover to know what happens, even if you only care about one specific character.
Saying that expressions independently denote a value is misleading. You can't know what an expression means without knowing the definition of each symbol it uses, and those symbols come from the expression's environment. These symbols may be defined in terms of other symbols, in turn, and the dependency graph of a large program is by no means simple.<p>Examples that use well-known mathematical functions give a misleading impression that such expressions will be easy to understand. Instead, it can become like puzzling over the meaning of the equations in a mathmatics paper. As the author discovered, this isn't always easy, particularly for unfamiliar mathematical objects, and it tends to appeal more to people with a background in mathematics.<p>Also notice that the focus on the <i>value</i> of an expression hides all performance issues. Maybe we can specify what an animation should do, but that doesn't mean it will run smoothly. It can be valuable to cleanly separate so-called "correctness" from performance (as if a program that's too slow is somehow correct?), but this doesn't relieve the programmer of the responsibility to work on performance. Languages that don't give you the tools to control performance are incomplete.
As with most if these things, the theory is fascinating. And then comes a contrived small code example... and the theory falls apart:<p>- the example is trivial<p>- the code example is extremely complicated for such a trivial example<p>- the code has to be explained in minute detail, with at least one visualization (better, two)<p>- and it still remains largely over complicated<p>I shudder to think of any non-trivial example with this approach. It will hardly be more comprehensible than existing RxJS or Redux code.
I have long thought that the Nygaard definition of a functional <i>program</i> was correct, but largely misunderstood.<p><pre><code> "A functional program is regarded as a mathematical function, describing a relation between input and output."
</code></pre>
I think this article is helpful in explaining how insightful that definition is. It's interesting to contrast that with his other classifications of major paradigms at that time. Particularly that of an Object Oriented program (he is one of the fathers of OO with Dahl), which is at odds with the modern viewpoint today ...<p>1. ProceduralProgramming. A program execution is regarded as a (partially ordered) sequence of procedure calls manipulating variables.<p>2. ConstraintProgramming. A program is regarded as a set of equations describing relations between input and output.<p>3. ObjectOrientedProgramming. A program execution is regarded as a physical model, simulating the behavior of either a real or imaginary part of the world.
I notice the mention of spreadsheets.<p>Something I never thought about until I started writing scripts in Excel is that when you define new functions to be used in cell formulas, they are not allowed to have side effects...and it didn't take long before I <i>wanted</i> to write functions with side effects.<p>Sure, this makes sense from a certain perspective, but when you're using a dialect of Basic, you kind of think it's down and dirty, anything goes. I mean, this is the language that used to usually have "peek" and "poke".
Nobody quickly understands:<p><pre><code> A(B(C(D(E(x)))))
</code></pre>
That is why they use the assignments.<p><pre><code> e= E(x)
d= D(e)
c= C(d)
b= B(c)
a= A(b)
</code></pre>
But many people can understand:<p><pre><code> x-> E -> F-> C-> B-> A
// where -> is a pipe operator.
</code></pre>
Now you see that you first execute E with x as input.<p>This shows that Functional program has some kind of problem, if it is not presented in a good way.<p>There are also other problems. The overuse of Currying is bad, as it hides what is going on. Then we can also have recursion mixed with lazy execution.<p>I think that the problem with functional programming is the bad presentation of what is really going on.<p>I try to overcome these problems by using a pure graphical system instead. Everything should be as simple and clear as possible.
The system is still in design/development, but you can see some at <a href="http://www.reddit.com/r/unseen_programming/" rel="nofollow">http://www.reddit.com/r/unseen_programming/</a><p>The general idea is that cells like in a spreadsheet are a basis for our functions. Unlike a spreadsheet-cell they can contain multiple variables. These cells can then be combined with pipes and streams. That may already define an functional language, but for me that is just the start.
For the author - it's "Salon de Refusés" not refuge.<p>i.e. "exhibition of rejects"<p><a href="https://2019.programming-conference.org/track/sdr-2019-papers" rel="nofollow">https://2019.programming-conference.org/track/sdr-2019-paper...</a>
The author comments often that there are certain concepts that 'belong in the implementation, not the surface', such as explicit sequences of operations and any interaction with the outside world.<p>I believe that this relegates DCTP to the status of a domain-specific language, not a general programming approach: if we know from the start that there are certain computations that we can't/don't want to perform with DCTP, then we know from the start that it only applies to certain domains of programming.<p>This isn't a problem in itself of course - DSLs can be wonderful things. But this can become a problem if you haven't taken the time to define the domain where your DSL is useful, or if that domain turns out to be extremely narrow. Spreadsheets are a wonderful abstraction for some things, but you wouldn't build an OS with them, nor even a simple web app.<p>Perhaps they can extend the abstraction until it can become 'nearly general-purpose' (after all, you wouldn't really write an OS in Java either), but I don't think that's guaranteed.
I spent a fair amount of time dabbling with FRP - for example, wrote a Pong for the web using SodiumFRP and Purescript[0]<p>imho FRP is absolutely elegant and wonderful when it all comes together. The difficulty, I found, is iterating and hacking away in order to discover what the end result was meant to be all along. In that respect FRP does slow down development time (at least in my hands. Maybe those with more expertise could iterate faster).<p>I'd imagine that even in that scenario it could be fruitful to use something less robust for prototyping, and then implement it with FRP for a maintainable release version that's easier to reason about.<p>[0] <a href="https://github.com/dakom/frpong" rel="nofollow">https://github.com/dakom/frpong</a>
I know you like to write HTML. But stop doing it! So how do you define view state without HTML? You use functions! Then you can use any paradigm you like. And you get performance. Static sites and static site generators is still a thing, but it works very different from a client side app. Then we have the in-between with an app that renders a static view on the server. But you have to stop writing client side apps like if they where server rendered.
This stuff is close-to-heart for me as FRP (and Elliott's work in general) greatly inspired my thinking over the years. Here are a few instances where the drive to be denotational in api design led to very satisfactory results. This is a massive "shameless plug" post, but I justify it as a dedication to Conal Elliott.<p>First, a couple of old talks on the topic -<p>- "Functional thinking" - Brings together some of the thinking I've applied in a few areas - <a href="http://sriku.org/blog/2015/08/11/talk-functional-thinking-for-fun-and-profit/" rel="nofollow">http://sriku.org/blog/2015/08/11/talk-functional-thinking-fo...</a> .<p>- "Beta abstraction for bottom-up theory building" - Shows how beta abstraction can be applied to systematically <i>become</i> denotational - <a href="http://sriku.org/blog/2016/02/06/beta-abstraction-for-bottom-up-theory-building/" rel="nofollow">http://sriku.org/blog/2016/02/06/beta-abstraction-for-bottom...</a><p>Systems -<p>- In "muvee Reveal", an automatic video production system, the styles are written in a Scheme-dialect called "muSE"[1] in which stuff needed to represent stylistic elements are built. The editing styles DSL [2] and documentation show how this stuff can be represented well removed from implementation details. (Disclaimer: I used to work for muvee, but no longer do so stuff may have changed.)<p>In particular, video and animations were not modeled as functions of time to Image, but functions of a time interval [t,t+dt] to Image. The reasoning was that the interval information is critical to render motion blur. You could argue that the "dt" is a detail that can be passed on later at render time, but it didn't take away much from the API's simplicity.<p>- Steller[3] - a library for declaratively composing dynamic temporal structures, useful (and used) for music and synchronized animations.<p>- elm-anima[4] - a concept demo of structuring animations in Elm. This was pre-18 and so doesn't use subscriptions. Here, animations are conceived of as processes rather than functions over time. I've described the thinking in a post [5]. Elm fell out of favour for me as there were many APIs I needed to work with that I couldn't use it with and the portion that needed Elm was small in the systems I was working with.<p>[1]: <a href="https://github.com/srikumarks/muSE" rel="nofollow">https://github.com/srikumarks/muSE</a><p>[2]: <a href="https://srikumarks.github.io/muvee-style-authoring/" rel="nofollow">https://srikumarks.github.io/muvee-style-authoring/</a><p>[3]: <a href="https://github.com/srikumarks/steller" rel="nofollow">https://github.com/srikumarks/steller</a><p>[4]: <a href="https://github.com/srikumarks/elm-anima" rel="nofollow">https://github.com/srikumarks/elm-anima</a><p>[5]: <a href="http://sriku.org/blog/2015/12/13/towards-reactive-animation-in-elm/" rel="nofollow">http://sriku.org/blog/2015/12/13/towards-reactive-animation-...</a>
The problem here is FRP is still immature and produces too much toy-ness. I've done some work in space, but the core of it is that the techniques are too expensive at the moment. This expense manifests in poor capacity utilization in the data center, and poor battery usage in mobile devices.