Hacker News new | past | comments | ask | show | jobs | submit login
The Misunderstood Roots of FRP (futureofcoding.org)
132 points by ecbu on Nov 2, 2019 | hide | past | favorite | 65 comments



Yeah okay. Then why does nobody use it? Even languages like Elm ditched it for easier to understand concepts.

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!

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.

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.


> How could we fit HTTP requests into the DCTP model? ... > HTTP requests are too low level ... We need to go higher level and build a denotative model for “whole systems.”

So this points out a flaw in thinking i think : that you own the whole system.

I think the reason FP and FRP is hard to use is because a lot of work involves interfacing with existing systems that are inherently created imperatively (the examples in the article - files, network IO, etc).

It is the same story as LISP machines - the idea is great, but the existing infrastructure and computing devices all rely on register based machines, and run imperative instructions means that at some point, somebody had to write code to work with those machines, and that code tends to infect upwards to the high-heavens of clean abstraction, taking it down. And this happens on every level - because one implementation details is another's interface.


>the existing infrastructure and computing devices all rely on register based machines, and run imperative instructions

I don't think the author is disputing this at all, but positing that for writing application layer programs this is unnecessary complexity and ought to be abstracted by the language/compiler. Perhaps as it stands our programming languages are too general purpose; in future, will we see a clearer distinction between languages for different purposes?


Kinda agree, but would add the counter point that it not being popular doesn't necessitate it being bad. We're also starting to see it become more mainstream, Rx* have been pretty popular on both mobile platforms for a while now. We've also just seen Apple release the Combine framework essentially making FRP a first class citizen in their SDKs.


Agreed, partly.

> 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.

People view some spreadsheet cells as state, and they view others as functions. There's a distinction between things that are naturally represented as one, vs the other.

This is why I preach to people about MobX whenever I get the chance. It's a Redux alternative that embraces state for things that make the most sense as state, while giving you tools to easily FRP not only React content, but any pure function of that state.


>> People view some spreadsheet cells as state...

But a cell with a function is not a function, it’s a result of calling a function at a certain set of values. That is even true if you only use ArrayFormula.

E.g. you can’t define a formula inside a cell and the call that cell with certain arguments.


The arguments are the other cells it references, which are themselves either state or other functions


Isn't Redux FRP? You can easily do the basics in React as well. I would say it's the dominant paradigm in UI development and most don't know they're using it.


Having worked with both Redux and a "real" FRP implementation (Haskell's Reflex library), I wouldn't call Redux FRP.

In Redux one explicitly, imperatively sends messages to a top-level message dispatcher, which then invokes more imperative code.

This feels /very/ different to Reflex's folding over events, and transforming dynamic values with pure functions.

The API you use is pretty different as well; consider:

* https://github.com/reflex-frp/reflex/blob/develop/Quickref.m...

* https://github.com/reflex-frp/reflex-dom/blob/develop/Quickr...


Completely agree Reflex is proper FRP. Redux does have some of the basics of FRP and you can stick to pure functions as well, which is limited by JS but not necessarily by the Redux pattern. I believe Redux is subset of FRP, that uses discrete commands instead of continuous function of time, and the time function can be made into descrete events for implementing commands. The rest builds on top of that.


To me, the core of FRP is hiding state. You couldn't look at a FRP program and say, "Yeah, here's where we define value X". Instead, you'd see various time-varying functions and the manner in which these functions are composed will implicitly define the state.

I think Redux isn't true FRP because it's very much about defining state. You plainly state every variable your program needs, while in FRP, variables just don't exist.


Hiding state is more the priority of declarative programming. FRP being declarative definitely does that, but I think the update loop is what's at the core of FRP, namely function changes over time and how they compose together to create chains of function changes over time, or something like that.


Sometimes it is tough to use theory directly, even when it is a sound theory. This can be disappointing for theorists and very frustrating for practitioners.


The author addresses some if not all of these points:

"It's awkward as hell to use and takes way to many brain-cells to achieve simple results."

> Even I find the above [react.js FRP] code hard to read, despite having written it! While this could be seen as a downside of the denotative approach, I see it as a mismatch between the denotative approach and textual syntax. There’s been interesting work visualizing streams, which I hope to build on. Currently, I’m in the mockup phase, but I hope to build a developer tool experience that will automatically generate a live visualization.

My understanding is that right now it certainly does require too much brain to do anything in FRP, but that isn't a downfall of FRP as a concept ("FRP kinda sucks") but rather that making FRP convenient is still today an open research question.

"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."

> Denotative languages better convey the global structure of a program. We can fully understand an expression by its subexpressions, and their subexpressions, recursively. There are no spooky action-at-a-distance side-effects that can manipulate things from afar. We don’t have to read the entire codebase to ensure we understand a single piece; we must merely read its subexpressions, recursively. This allows us to quickly rule out what we do and do not need to read, saving us a lot of time in large codebases.

I don't disagree that using concrete, non-abstracted state is a simpler way to model state-related problems, but this isn't about modeling and solving state-related problems, it's about solving them in a way that's maintainable. It's easy to argue for simplicity now (i.e. when first approaching a problem) and we have many, many tools for using state for that, like ipython notebooks, or pen and paper. But let's point out that simplicity of these initial concrete-state-minded approaches tend to grow into entangled messes, messes that are arguably solved by encapsulation and patterns. Regardless of whether they do solve the problem, having to understand things like inheritance and all their related problems kind of defeats the purpose of using state to make the problem simpler to understand in the long run. Which is what FRP purports to solve. Except we don't have the pen and paper for FRP yet.

"The great irony is that nobody on the planet thinks of spreadsheets as time-varying continuous functions."

True. No one thinks that. The author doesn't think that. Probably not even the folks who made the neat stats-oriented spreadsheet[0] thinks that, and that's data as continuously varying as you can get.

All of this kind of props up the title which is that FRP is grossly misunderstood.

[0] https://news.ycombinator.com/item?id=18785371


Step 1: when selling something, it helps to explain what it is and why it is good.


I use it professionally.


The Svelte framework is something that's pretty close to being truly reactive. Not functional though.


Yep completely agree. FRP sucks. FP rocks.


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:

    celsiusTextbox.whenChanged do
        fahrenheitTextbox.value = cToF(celsiusTextbox.value)
    end
What you wouldn't 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.

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.


Yeah. More power to people like this who are trying to make pure-functionalism more accessible and practical, but I have my doubts that contorting logic that's naturally stateful into a denotational paradigm will ever feel natural or intuitive. Human intuition is rooted in navigating the physical world, and imperative/cause-and-effect thinking is a very physical way of accomplishing things.


Thinking about things like this is really tiring, but I suspect I get less bugs when I do.


Won't your example trigger an infinite loop of celsius/fahrenheit conversions? Especially if the floating point value is slightly off.

I think your example is exactly why stuff like React won vs data-binding frameworks. With declarative programming, you just have a single source of truth that you change once (you can arbitrarily pick celsius or fahrenheit or even kelvin) and let the framework figure out what needs to be diff-ed in the derived views.


I'm not aware of any actual real-world GUI system where ".whenChanged do" is valid syntax, but just for the sake of argument, pretend that it only fires when the user changes the textbox. Coincidentally, this also happens to be how the "change" event works in JavaScript.


I know of one that's essentially like that [0], but like you suggested - it only fires on user action, not programmatic update.

(The examples here are for buttons and sliders, but it's the same syntax for input fields)

[0] http://rebol.com/docs/easy-vid.html#section-20


When working on GUIs that used callbacks like this, I’d have a method for setting the value of the second component which didn’t raise a ’changed’ event, or I’d turn off raising events for the second component before telling it to change then tell it to continue.

They weren’t beautiful, but both methods worked fine for the rare cases they proved necessary.


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.

I think an example of database programming in "Continuous Time" would be

    (datomic.api/q '[:in $ :find ?e :where [?e :post/title]] db)
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)

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.

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!


You can think of a timeline as immutable, but you don't know values from the past unless you arranged for them to be recorded, you don't know values from the future until they happen, and you don't know what's going on at any other node unless they send you a message about it and it eventually makes it across an unreliable network. (So, sometime after it actually happened.)

If you model this in a declarative way then you have to be careful to avoid implying that all events should be remembered, and also avoid depending on anything in the future unless you want to wait for it. This makes designing an intuitive FRP-based language pretty hard.


> be careful to avoid implying that all events should be remembered

Is that true in a post-AWS world with storage getting cheaper faster than you can consume it? Maybe don't put 4k video in the log. But, you're right, we can stream, shard and forget as necessary.

> also avoid depending on anything in the future unless you want to wait for it

Can you elaborate on this, my gut reaction is to ask why I need to avoid depending on git commits that haven't been written yet – it's kind of a weird question right? Time is explicit now, which means you have the right knobs you need to coordinate it, even across distributed nodes.


> Is that true in a post-AWS world with storage getting cheaper faster than you can consume it?

This might be true of "storage" as in disk space, but it definitely isn't true of "storage" as in RAM. If your phone kept an in-memory log of every single click event, you'd run out of RAM pretty fast.


If you use a value to do a calculation and it's from the future then often you end up blocking until it's available. This is how a Future works and is similar to what happens when you read from a TCP connection and the data has to be retransmitted because the network dropped the packet, so you block. If you want responsive output then you should avoid blocking or at least have a timeout and/or cancel button.

The conceptual idea of a value that continuously changes is nice for animation or maybe video (though that's both discrete and lossy), but seems messier when your knowledge is limited to an unknown selection of discrete data points from that timeline, arriving with an unknown amount of lag? Maybe you could talk about that mathematically, but it seems like it's going to be rather abstract and messy.


i think it falls into the slightly-too-clever category, but http://www.neilconway.org/docs/vldb2014_edelweiss.pdf treats safe log truncation as a conservative optimization.

its similar to tail-call in that the efficacy of your program depends on the compiler figuring out what you're trying to do - which is unsatisfying

but its a great idea and a ray of hope here

edit: this also implies that the set of reads against the history is fully known at compile time - which may make it irrelevant depending on the usage


> This makes designing an intuitive FRP-based language pretty hard.

Yet, I fail to see any other representation where it is viable to solve those problems in a generic way.

If we want to get something better than our current "it's impossible, better not even try" posture, we better look for it somewhere where it is possible.


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.

I like FP because it allows me to be lazy; quoting the author:

> 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.

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.

Also notice that the focus on the value 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:

- the example is trivial

- the code example is extremely complicated for such a trivial example

- the code has to be explained in minute detail, with at least one visualization (better, two)

- and it still remains largely over complicated

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 kindof wonder if this isn't one of those things that falls flat because it's a toy example, and anything but the most direct approach is going to look clumsy and over-engineered.

I've spent a bunch of time working in Elm, though I hadn't used it in anger before they dropped the FRP stuff.

My experience with post-frp Elm is that:

* It seems really elegant on small examples * When you start working with larger codebases, and you have some resuable UI elements you want to build, you end up writing a lot of "routing" code to shunt messages to sub-components. Conventional wisdom in the community is to try to keep app structure as "flat" as you can to avoid this, but I've not seen a codebase of meaningful size where this doesn't happen enough to be annoying.

I have a gut instinct that "real FRP" might shine a bit more at this point; it seems like it would make wiring together different bits of the UI easier.


And the author admits as much:

> Even I find the above code hard to read, despite having written it! While this could be seen as a downside of the denotative approach, I see it as a mismatch between the denotative approach and textual syntax.

Clearly, from this piece and his site as a whole, he’s looking at the long-term picture. Maybe there’s no way to make this better, but we’ve been stuck with the same basic models for decades. I’m glad people are looking for more revolutionary ways to make programming more powerful.


I have long thought that the Nygaard definition of a functional program was correct, but largely misunderstood.

   "A functional program is regarded as a mathematical function, describing a relation between input and output."
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 ...

1. ProceduralProgramming. A program execution is regarded as a (partially ordered) sequence of procedure calls manipulating variables.

2. ConstraintProgramming. A program is regarded as a set of equations describing relations between input and output.

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.

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 wanted to write functions with side effects.

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".


For better or worse, Google Sheets functions (written in App Script) are allowed to have side effects. Though when invoked in cells, you don't have full control over when they're actually recalculated (there seems to be complex caching), so you need to plan your side effects accordingly.


If you use Microsoft's C SDK then you can write functions with limited side effects by declaring the function "uncalced". For example, you can peek at the current cell value of the function being called.


Nobody quickly understands:

    A(B(C(D(E(x)))))
That is why they use the assignments.

    e= E(x)  
    d= D(e)  
    c= C(d)  
    b= B(c)  
    a= A(b)
But many people can understand:

    x-> E -> F-> C-> B-> A  
    // where -> is a pipe operator.
Now you see that you first execute E with x as input.

This shows that Functional program has some kind of problem, if it is not presented in a good way.

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.

I think that the problem with functional programming is the bad presentation of what is really going on.

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 http://www.reddit.com/r/unseen_programming/

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.


The first line seems the most easily parsed to me. The second one is the worst, and the third one only works for a tidy pipeline; if you have to combine multiple pipelines you'd need to bracket them, as in the first.


> The first line seems the most easily parsed to me. The second one is the worst, and the third one only works for a tidy pipeline;

I'd take the second over the other ones any time of the day, which clearly shows that there is no actual problem to solve here : we all see the world differently and there's nothing anyone can do about that.


You must be used to reading inside out, instead of left to right.

The parameters will mess up as soon you have multiple parameters. Especially messy if you want to reuse them. Or when you have conditions.

In a graphical system you do not need brackets, which is why I added it as a possible solution.


The first and third are both easier for me than the second.

At least in my case, it's not an inside-out or left-right thing, it's a funnel that shows the exact relationship of the data. The problem with the second one is that the multiple distinct statements require scanning up and down across them to ensure the local variables aren't used anywhere else, and then mentally reconstructing the data's flow from one function to the next.

It's also why I strongly prefer statements like this:

  A(
    B(C),
    D,
    E(F(G))
  )
The flow of data is encoded directly in the visual structure, instead of being split out across various statements using local variables that leak intermediate state and introduce accidental mental overhead.


But the second form is also more general, since you can express any computation that way, whereas you can't in the first or third forms.

For example:

    x = A(B)
    y = D(x) 
    z = C(x, E(y)) 
Is either an important optimization (possibly affecting asymptotic complexity in more complex cases), important for correctness (if any of the functions have side-effects), or at least more succint than the alternatives (in a lazy language like Haskell).


The first line makes it hard to parse actual diffs in git.


For the author - it's "Salon de Refusés" not refuge.

i.e. "exhibition of rejects"

https://2019.programming-conference.org/track/sdr-2019-paper...


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.

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.

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.

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]

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).

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.

[0] https://github.com/dakom/frpong


What did you find that you had to hack away? Was it notions of how to do things from your previous experience as a programmer? Or was it more specific to the domain problem at hand?

If it's the latter, then I'd argue that's part of the exploration of the problem you're trying to solve, no?


Hmmm good question! I can't say for sure - I guess it was a bit of both.

In either case, I found it's faster to play around with changes in other approaches, though another way of phrasing that could be that it's easier to break things too :)


What’s FRP?


I had the same question. Functional Reactive Programming.


Thanks. I'll recite the rule of acronyms and articles: Always define all acronyms in your article.


yep. i knew in our field the F & P could only mean functional programming. but the R eluded my acronym decrypting skills. glad to find someone found what it meant. i almost thought it was "recursive"...

can we agree to stop using these meaningless acronyms?!


You just have to spell it out once at the beginning of the article, then it's fine. The author never did it once.


The site is "Future of Coding". He assumed most of his audience were language wonks, and you don't have to go far to run into FRP.

That said, it's best not to assume.


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.

First, a couple of old talks on the topic -

- "Functional thinking" - Brings together some of the thinking I've applied in a few areas - http://sriku.org/blog/2015/08/11/talk-functional-thinking-fo... .

- "Beta abstraction for bottom-up theory building" - Shows how beta abstraction can be applied to systematically become denotational - http://sriku.org/blog/2016/02/06/beta-abstraction-for-bottom...

Systems -

- 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.)

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.

- Steller[3] - a library for declaratively composing dynamic temporal structures, useful (and used) for music and synchronized animations.

- 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.

[1]: https://github.com/srikumarks/muSE

[2]: https://srikumarks.github.io/muvee-style-authoring/

[3]: https://github.com/srikumarks/steller

[4]: https://github.com/srikumarks/elm-anima

[5]: http://sriku.org/blog/2015/12/13/towards-reactive-animation-...


What did you replace Elm with in your later work with FRP systems?

Also, with your Elm-anima project, what were the lessons and takeaways? It seemed like it was working, but what are the limitations of the approach?


I wrote a small JS "framework" that's not even worth that name, but which works well enough by decoupling components CSP style. The HTML rendering part was not the most complex piece in the system (it was webaudio code, wasm, etc. dominated) to warrant dependency on a language so the additional complexity wasn't worth it.

Elm-anima - yes I felt that the elm-anima approach worked fine conceptually and is fairly performant too with scope to inject caching and laziness, but its approach ran into 0.18 's subscription mechanism (it was done before subscriptions) and I couldn't wrap my head around the loss of control there for this purpose. Things didn't compose after that.

Edit: elm-anima also needs more work to support effects, without burdening the API too much, to be truly useful.

Personally, I'd have liked the whole program in Elm to be modeled as just an "Automaton Input (Html, Task x ())" or something. That would've given enough freedom to do these kinds of things and, with some effort, be performant too.


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.


Even the article doesn't explain what FRP is . . .




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: