Skip to content

Commit 6203d4c

Browse files
author
Steve Krouse
committed
edited frp essay, and reorganized todos
1 parent e7236cc commit 6203d4c

File tree

1 file changed

+39
-38
lines changed

1 file changed

+39
-38
lines changed

drafts/frp.md

Lines changed: 39 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -2,24 +2,26 @@
22
title: FRP
33
---
44

5-
# Explicit Functional Reactive Programming
5+
# Dependable Functional Reactive Programming
66

77
* TOC
88
{: toc }
99

1010
## 1. Introduction
1111

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?
1313

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

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

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

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]
2121

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

2426
## 2. The Elm Architecture
2527

@@ -29,55 +31,54 @@ The Elm Architecture follows directly from Elm's first-order, non-cyclic nature:
2931

3032
<iframe width="500" height="300" src="https://mermaidjs.github.io/mermaid-live-editor/#/view/eyJjb2RlIjoiXG5ncmFwaCBURFxuIFxucmVkdWNlci0tPiBzMihuZXcgc3RhdGUpXG5zMihuZXcgc3RhdGUpIC0tPiB2aWV3IFxudmlldy0tPnxldmVudCwgb2xkIHN0YXRlfHJlZHVjZXJcbiIsIm1lcm1haWQiOnsidGhlbWUiOiJkZWZhdWx0In19" frameborder="0" allowfullscreen></iframe>
3133

32-
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...?]
3335

3436
```haskell
3537
reducer :: state -> event -> state
3638
```
3739

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/Redux and Elm 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 Elm Architecture 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/Redux and Elm 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.
4541

46-
Any message can modify any state. In the reducer, called `update` in [Elm ToDoMVC](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 Elm Architecture is explict only about the *initial* values of states.A ny message can modify any state. In the reducer (called `update` in [Elm ToDoMVC](https://github.com/evancz/elm-todomvc/blob/master/Todo.elm)), the `Add` message triggers an update of three different pieces of state:
4743

4844
![image](https://user-images.githubusercontent.com/2288939/42886488-ab1c24c4-8a71-11e8-92f5-13dc2f282ad4.png)
4945

50-
This means that you can't modularly gain a complete understanding of any piece of state. You have to look through *all* messages to see if and how it affects the state in question.
46+
You can't gain a complete understanding of any piece of state by looking in one place. You have to look through *all* messages to see if and how each affects the state in question.
5147

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

5450
Additionally, any view element can emit any message. Again from [Elm ToDoMVC](https://github.com/evancz/elm-todomvc/blob/master/Todo.elm), the viewInput's `onInput` and `onEnter` events send `UpdateField` and `Add` messages, respectively:
5551

5652
![image](https://user-images.githubusercontent.com/2288939/42886260-13e14bb6-8a71-11e8-8961-044c1a596b8a.png)
5753

58-
If were looking to understand a single piece of state, were not much better off than with an entirely imperative framework: we still have to read more-or-less the whole application even if 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 even if we wish only to comprehend only a small piece.
5955

6056
## 3. Reflex
6157

62-
The Reflex library was built for Haskell web development via ghcjs. It features higher-order and cyclic streams.
63-
64-
## ToDo
65-
66-
* maybe reverse 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 in Elm to decrease coupling. [3]
76-
* Reflex
77-
* what does foldDyn do and 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+
The Reflex 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 in FRP.
59+
60+
* compare ToDoMVC to Elm
61+
* what does foldDyn do and 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 in JS 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 - maybe in JS
78+
79+
## 7. Conclusions
80+
81+
TODO
8182

8283

8384
<script>

0 commit comments

Comments
 (0)