You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: drafts/frp.md
+39-38Lines changed: 39 additions & 38 deletions
Original file line number
Diff line number
Diff line change
@@ -2,24 +2,26 @@
2
2
title: FRP
3
3
---
4
4
5
-
# Explicit Functional Reactive Programming
5
+
# Dependable Functional Reactive Programming
6
6
7
7
* TOC
8
8
{: toc }
9
9
10
10
## 1. Introduction
11
11
12
-
When trying to understand a small piece of a large software project, explicit dependencies clarify which sections of code are independent to our current investigations, keeping the "effort needed to concieve or to understand a program ... not more than proportional to the program length" [Humble Programmer].
12
+
Today software projects are so large that programmers them in their entirety. So how is one to know which lines to read and which they can safely ignore? In other words, we wish to know the relationships between various pieces of state: are they depedent or independent?
13
13
14
-
Explict data relationships is one of the benefits of functional programming, because all terms explicitly list what they depend upon. This contrasts with imperitive programming, where terms can "be dependent on many, many different hidden mutable variables" [Out of the Tarpit].
14
+
This question is incredibly difficult to answer in imperative programming languages with mutable state, where variables can be modified anywhere they are in scope.
15
15
16
-
However, functional programming can simulate "hidden mutable variables" via an compound state value that it passes around as an extra parameter:
16
+
In functional programming without mutable state, all terms explicitly list what they depend. Definitions are final and cannot be modified elsewhere in the code. This explicitness makes it incredibly easy to determine which parts of the code are depedent and independent of each other, and guide us towards what we do and do not need to read for our present purposes.
17
17
18
-
> There is in principle nothing to stop functional programs from passing a single extra parameter into and out of every single function in the entire system. If this extra parameter were a collection (compound value) of some kind then it could be used to simulate an arbitrarily large set of mutable variables. In effect this approach recreates a single pool of global variables — hence, even though referential transparency is maintained, ease of reasoning is lost (we still know that each function is dependent only upon its arguments, but one of them has become so large and contains irrelevant values that the benefit of this knowledge as an aid to understanding is almost nothing). [Out of the Tarpit]
18
+
However, functional programming does not guarantee explict data relationships. It is still possible to obfustate the relationships between pieces of state. One can simulate mutable state by passing around an arbitrarily large compound state value as an extra parameter to each function.
19
19
20
-
While this is considered an anti-pattern in many functional programming settings [TODO source needed], a variation on it has become the dominant architecture in Functional Reactive Programming. Originally concieved for the Elm programming langauge, The Elm Architecture has since inspired ReactJS's Redux, VueJS's Vuex, CycleJS's Onionify, among many other front-end state management libraries. [TODO source needed]
20
+
This is considered an anti-pattern because "ease of reasoning is lost (we still know that each function is dependent only upon its arguments, but one of them has become so large and contains irrelevant values that the benefit of this knowledge as an aid to understanding is almost nothing)." [Out of the Tarpit]
21
21
22
-
This paper contrasts the Elm Architecture with Haskell's Reflex, featuring higher-order streams and cyclic streams, with an eye towards idepedent comprehensibility through explicit data dependencies.
22
+
Yet in Functional Reactive Programming (FRP) this a variation on this anti-pattern has recently become the dominant architecture. Originally concieved for the Elm programming langauge, The Elm Architecture has since inspired ReactJS's Redux, VueJS's Vuex, CycleJS's Onionify, among many other front-end state management libraries. [TODO source needed]
23
+
24
+
This paper contrasts The Elm Architecture with a state management pattern that maintains explicit relationships.
23
25
24
26
## 2. The Elm Architecture
25
27
@@ -29,55 +31,54 @@ The Elm Architecture follows directly from Elm's first-order, non-cyclic nature:
The core of this architecture is its a compound state value, which along with the reducer, which returns a new state in response to events, "simulate[s] an arbitrarily large set of mutable variables." [Tarpit]
34
+
The core of the architecture is its a compound state value. It represents the entirety of an applications state at any given time. The reducer steps the state forward in response to events, thus simulating mutable variables that change over time. In this way, the Elm Architecture simulates the "primitive word-at-a-time style of program-ming inherited from the von Neumann computer ... instead of encouraging us to think in terms of the larger conceptual units of the task at hand." [Can Programming Be Liberated...?]
33
35
34
36
```haskell
35
37
reducer::state->event->state
36
38
```
37
39
38
-
The view is a pure function of state.
39
-
40
-
The way the view sends events to the `reducer` differs between frameworks.CycleJS derives event information *outside* the view, such as `const clicks =DOM.select('#counter-button').events('click')`.React/ReduxandElm generate events from *within* view, such as `<button onClick={this.handleClick()}>` or `button [ onClick Increment ]`, respectively.
41
-
42
-
Additionally, these frameworks sometimes wrap events in semantic labels called "actions"or"messages".For example, an `onClick` event can be labeled as the `Increment` action.This will become clearer in the Elm example below.
43
-
44
-
Just like in imperitive programming, the ElmArchitecture is explict only about the *initial* values of states.
40
+
The view is a pure function of state.The way the view sends events to the `reducer` differs between frameworks.CycleJS derives event information *outside* the view, such as `const clicks =DOM.select('#counter-button').events('click')`.React/ReduxandElm generate events from *within* view, such as `<button onClick={this.handleClick()}>` or `button [ onClick Increment ]`, respectively.Additionally, these frameworks sometimes wrap events in semantic labels called "actions"or"messages".For example, an `onClick` event can be labeled as the `Increment` action.This will become clearer in the Elm example below.
45
41
46
-
Anymessage can modify any state.In the reducer, called `update`in [ElmToDoMVC](https://github.com/evancz/elm-todomvc/blob/master/Todo.elm), the `Add` message triggers an update of three different pieces of state:
42
+
Just like in imperitive programming, the ElmArchitecture is explict only about the *initial* values of states.A ny message can modify any state.In the reducer (called `update`in [ElmToDoMVC](https://github.com/evancz/elm-todomvc/blob/master/Todo.elm)), the `Add` message triggers an update of three different pieces of state:
This means that you can't modularly gain a complete understanding ofany piece of state.You have to look through *all* messages to see ifand how it affects the state in question.
46
+
Youcan't gain a complete understanding ofany piece of state by looking in one place.You have to look through *all* messages to see ifand how each affects the state in question.
51
47
52
-
There's also a subtler way this undermines explicit dependencies: each piece of state can be modified in terms of*any other piece of state*.There's no explicit isolation between independent states.
48
+
There's also a subtler way this undermines explicitness: each piece of state can be modified in terms of*any other piece of state*.There's no explicit isolation between independent states.
53
49
54
50
Additionally, any view element can emit any message.Again from [ElmToDoMVC](https://github.com/evancz/elm-todomvc/blob/master/Todo.elm), the viewInput's `onInput`and`onEnter` events send `UpdateField` and `Add` messages, respectively:
If we’re looking to understand a single piece of state, we’re not much better off than with an entirely imperative framework: we still have to read more-or-less the whole application evenif we wish only to comprehend only a small piece.
54
+
If we're looking to understand a single piece of state, we're not much better off than with an entirely imperative framework: we still have to read more-or-less the whole application evenif we wish only to comprehend only a small piece.
59
55
60
56
## 3. Reflex
61
57
62
-
TheReflex library was built for Haskell web development via ghcjs.It features higher-order and cyclic streams.
63
-
64
-
## ToDo
65
-
66
-
*maybereverse the order of the introduction
67
-
* be clearer on what explicit means
68
-
*data=...
69
-
* inversion of control (http://degoes.net/articles/destroy-all-ifs)
70
-
* explicit in the math formula sense
71
-
* the elm architecture section
72
-
*maybe simulates von-neuman, one word at a time
73
-
* argue that it's difficult to mechanically convert to explicit form
74
-
* argue the treatment is *not* worse than the disease
75
-
*This design decision was made consciously inElm to decrease coupling. [3]
76
-
*Reflex
77
-
* what does foldDyn doand what's its type?Show how the stream is higher order.Also note the dependency on lazy eval which is part of the reason for space leakiness.
78
-
*TodoMVC comparison
79
-
* title
80
-
* spell check (again)
58
+
TheReflex library was built for Haskell web development via ghcjs.It features higher-order and cyclic streams, which means that streams can contain streams, and streams can reference streams that reference themselves.It is these features that are neccesary to maintain explicitness inFRP.
59
+
60
+
*compareToDoMVC to Elm
61
+
* what does foldDyn doand what's its type?Show how the stream is higher order.
62
+
63
+
## 4. Is the cure worse than the disease?
64
+
65
+
* how the elm architecure is good
66
+
* why higher order and cyclic streams are difficult
67
+
*Also note the dependency on lazy eval which is part of the reason for space leakiness.
68
+
* possible inJS without Haskell-y runtime?
69
+
70
+
## 5. Related Work
71
+
72
+
* program slicing (and the other one)
73
+
74
+
## 6. Future work
75
+
76
+
*Visualizations
77
+
*Building a langauge that's easier to use -maybeinJS
0 commit comments