WIP docs
This commit is contained in:
parent
46380182fb
commit
189709f65f
|
@ -7,12 +7,12 @@ patterns of thought that produced that government are left intact,
|
|||
then those patterns will repeat themselves. <br>
|
||||
> -- Robert Pirsig, Zen and the Art of Motorcycle Maintenance
|
||||
|
||||
The re-frame docs initially focus on the **domino cascade
|
||||
The re-frame docs initially focus on the **domino cascade
|
||||
narrative**. The goal was to efficiently explain the mechanics,
|
||||
and get you reading and writing code ASAP.
|
||||
|
||||
**But** there's other interesting perspectives on re-frame
|
||||
which will considerably deepen your understanding of its design,
|
||||
**But** there's other interesting perspectives on re-frame
|
||||
which will considerably deepen your understanding of its design,
|
||||
and how to get the best from it.
|
||||
|
||||
This tutorial is a tour
|
||||
|
@ -29,7 +29,7 @@ choose [Reagent], then we had a problem. It was mid to late 2014.
|
|||
For all its considerable brilliance, Reagent (+ React)
|
||||
delivers only the 'V' part of a traditional MVC framework.
|
||||
|
||||
But apps involve much more than V. We tend to build quite complicated
|
||||
But apps involve much more than V. We tend to build quite complicated
|
||||
apps. Where does the control logic go? How is state stored & manipulated? etc.
|
||||
|
||||
We read up on [Pedestal App], [Flux],
|
||||
|
@ -38,7 +38,7 @@ emerged. Since then, we've tried to kept an eye on further developments like th
|
|||
Elm Architecture, Om.Next, BEST, Cycle.js, Redux, etc. They have taught us much
|
||||
although we have often made different choices.
|
||||
|
||||
re-frame does have M, V, and C parts but they aren't objects.
|
||||
re-frame does have M, V, and C parts but they aren't objects.
|
||||
It is sufficiently different in nature
|
||||
from (traditional, Smalltalk) MVC that calling it MVC would be confusing. I'd
|
||||
love an alternative.
|
||||
|
@ -90,36 +90,36 @@ You design what's flowing and then you hang functions off the loop at
|
|||
various points to look after the data's phase changes.
|
||||
|
||||
Sure, right now, you're thinking "lazy sod - make a proper Computer Science-y diagram". But, no.
|
||||
Joe Armstrong says "don't break the laws of physics" - I'm sure
|
||||
Joe Armstrong says "don't break the laws of physics" - I'm sure
|
||||
you've seen the videos - and if he says to do something, you do it
|
||||
(unless Rich Hickey disagrees, and says to do something else). So,
|
||||
this diagram, apart from being a plausible analogy which encourages
|
||||
this diagram, apart from being a plausible analogy which encourages
|
||||
you to look differently at re-frame, is **practically proof** it does physics.
|
||||
|
||||
## It does Event Sourcing
|
||||
|
||||
How did that exception happen, you puzzle, shaking your head?
|
||||
What did the user do immediately prior to the exception? What
|
||||
state was the app in that this event was so disastrous?
|
||||
How did that error happen, you puzzle, shaking your head ruefully?
|
||||
What did the user do immediately prior? What
|
||||
state was the app in that this event was so problematic?
|
||||
|
||||
To debug, you need to know this information:
|
||||
1. the state of the app immediately before the exception
|
||||
2. What final `event` then caused your app to fall in a screaming mess
|
||||
2. What final `event` then caused your app to error
|
||||
|
||||
Well, with re-frame you need to record (have available):
|
||||
1. A recent checkpoint of the application state in `app-db` (perhaps the initial state)
|
||||
2. all the events `dispatch`ed since the last checkpoint, up to the point where the exception occurred
|
||||
2. all the events `dispatch`ed since the last checkpoint, up to the point where the error occurred
|
||||
|
||||
Note: that's all just data. **Pure, lovely loggable data.**
|
||||
|
||||
If you have that data, then you can reproduce the exception.
|
||||
If you have that data, then you can reproduce the error.
|
||||
|
||||
re-frame allows you to time travel, even in a production setting.
|
||||
Install the "checkpoint" state into `app-db`
|
||||
and then "play forward" through the collection dispatched events.
|
||||
|
||||
The only way the app "moves forwards" is via events. "Replaying events" moves you
|
||||
step by step towards the exception causing problem.
|
||||
step by step towards the error causing problem.
|
||||
|
||||
This is perfect for debugging assuming, of course, you are in a position to capture
|
||||
an app state checkpoint, and the events since then.
|
||||
|
@ -132,7 +132,7 @@ Here's an interesting way of thinking about the re-frame
|
|||
data flow ...
|
||||
|
||||
**First**, imagine that all the events ever dispatched in a
|
||||
certain running app were stored in a collection.
|
||||
certain running app were stored in a collection (yes, event sourcing again).
|
||||
So, if when the app started, the user clicked on button X
|
||||
the first item in this collection would be the event
|
||||
generated by that button, and then, if next the user moved
|
||||
|
@ -142,16 +142,14 @@ collection of event vectors.
|
|||
|
||||
**Second**, remind yourself that the `combining function`
|
||||
of a `reduce` takes two parameters:
|
||||
|
||||
1. the current state of the reduction and
|
||||
2. the next collection member to fold in.
|
||||
|
||||
Then notice that `reg-event-db` event handlers take two parameters too:
|
||||
Then notice that `reg-event-db` event handlers take two parameters also:
|
||||
1. `db` - the current state of `app-db`
|
||||
2. `v` - the next event to fold in
|
||||
|
||||
1. `db` - the current state of `app-db`
|
||||
2. `v` - the next event to fold in
|
||||
|
||||
Which is the same as a `combining function` in a `reduce`!!
|
||||
Interesting. That's the same as a `combining function` in a `reduce`!!
|
||||
|
||||
So now we can introduce the new mental model: at any point in time,
|
||||
the value in `app-db` is the result of performing a `reduce` over
|
||||
|
@ -173,16 +171,32 @@ and interesting mental model. We first saw it in Elm's early use
|
|||
of `foldp` (fold from the past), which was later enshrined in the
|
||||
Elm Architecture.
|
||||
|
||||
And for the love of all that is good, please watch this terrific
|
||||
[StrangeLoop presentation ](https://www.youtube.com/watch?v=fU9hR3kiOK0) (40 mins).
|
||||
See what happens when you re-imagine a database as a stream!! Look at
|
||||
all the problems that are solved.
|
||||
Think about that: shared mutable state (the root of all evil),
|
||||
re-imagined as a stream!! Blew my socks off.
|
||||
|
||||
If, by chance, you do watched that video, you might twig to
|
||||
the idea that `app-db` is really a derived value .. the video tals
|
||||
a lot about derived values. So, yes, app-db is a derived value of the `perpetual reduce`.
|
||||
|
||||
And yet, it acts as the authoritative source of state in the app. And yet,
|
||||
it isn't, it is simply a piece of derived state. And yet, it is the source.
|
||||
|
||||
This is an infinite loop of sorts. An infinite loop of derived data.
|
||||
|
||||
## It does FSM
|
||||
|
||||
> Any sufficiently complicated GUI contains an ad hoc,
|
||||
> informally-specified, bug-ridden, slow implementation
|
||||
> of a hierarchical Finite State Machine <br>
|
||||
> -- [my eleventh rule](https://en.wikipedia.org/wiki/Greenspun%27s_tenth_rule)
|
||||
> -- [my 11th rule](https://en.wikipedia.org/wiki/Greenspun%27s_tenth_rule)
|
||||
|
||||
`event handlers` collectively
|
||||
implement the "control" part of an application. Their logic
|
||||
interprets arriving events in the context of existing state,
|
||||
`event handlers` collectively
|
||||
implement the "control" part of an application. Their logic
|
||||
interprets arriving events in the context of existing state,
|
||||
and they "step" the application state "forward" via modification of that state.
|
||||
|
||||
`events` act, then, a bit like the `triggers` in a finite state machine, and
|
||||
|
@ -221,25 +235,14 @@ Events are data - `[:delete-item 42]`
|
|||
That's almost like a function call `(delete-item 42)`. Kinda. So why prefer data?
|
||||
|
||||
Using data gives us:
|
||||
- easier hot reloading ??
|
||||
- late binding
|
||||
- logability and event sourcing
|
||||
- a more flexible version of "partial" (curring)
|
||||
|
||||
## Derived Data
|
||||
|
||||
There's a video I'd like you to watch from
|
||||
[StrangeLoop](https://www.youtube.com/watch?v=fU9hR3kiOK0) (40 mins, sorry).
|
||||
|
||||
XXX
|
||||
|
||||
If you have then, given the explanation above, you might twig to the idea that `app-db` is
|
||||
really a derived value (of the `perpetual reduce`).
|
||||
|
||||
And yet, it acts as the authoritative source of state in the app. And yet, it isn't, it is simply
|
||||
a piece of derived state. And
|
||||
yet, it is the source.
|
||||
|
||||
Hmm. This is an infinite loop of sorts. **Derived data is flowing around the
|
||||
**Derived data is flowing around the
|
||||
loop, reactively, through pure functions.** There is a pause in the loop whenever we wait
|
||||
for a new event, but the moment we get it, it's another iteration of the "derived data" FRP loop.
|
||||
|
||||
|
|
|
@ -29,14 +29,13 @@ Perhaps:
|
|||
**completely change everything**? And, if so, what would that look like in a language
|
||||
that embraces those paradigms?
|
||||
3. You're taking a [Functional Design and Programming course at San Diego State University](http://www.eli.sdsu.edu/courses/fall15/cs696/index.html)
|
||||
and you have to learn re-frame to do an assignment. You've left it a bit late, right?
|
||||
Good news, there is a quick start guide coming up shortly.
|
||||
4. You like social proof!!
|
||||
re-frame is impressively buzzword compliant: it has reactivity,
|
||||
unidirectional data flow, pristinely pure functions,
|
||||
and you have an assignment due. You've left the reading a bit late, right? I remember those days.
|
||||
4. Cromulent neologisms embiggen social proof!! We all know that. Luckily,
|
||||
re-frame is impressively buzzword compliant: it has reactivity,
|
||||
unidirectional data flow, pristinely pure functions,
|
||||
interceptors, coeffects, conveyor belts, statechart-friendliness (FSM)
|
||||
and claims an immaculate hammock conception. It also has a charming
|
||||
xkcd reference (soon) and a hilarious, insiders-joke T-shirt,
|
||||
and claims an immaculate hammock conception. It also has a charming
|
||||
xkcd reference (soon) and a hilarious, insiders-joke T-shirt,
|
||||
ideal for conferences (in design). What could possibly go wrong?
|
||||
|
||||
## re-frame
|
||||
|
@ -157,7 +156,7 @@ similar 5 domino cascade will happen again.
|
|||
|
||||
**Each of the dominoes you supply are simple, pure functions** which
|
||||
can be be described, understood and
|
||||
tested independently (other than domino 3). They take data, transform it and return new data.
|
||||
tested independently. They take data, transform it and return new data. (Other than domino 3)
|
||||
|
||||
The loop itself is utterly predictable and very mechanical in operation.
|
||||
So, there's a regularity, simplicity and
|
||||
|
@ -194,17 +193,19 @@ Data - that's the way we roll.
|
|||
|
||||
### It is both mature and successful in the large
|
||||
|
||||
re-frame was released early 2015, and has since been successfully
|
||||
re-frame was released early 2015, and has since [been](https://www.fullcontact.com)
|
||||
successfully
|
||||
[used](https://www.nubank.com.br)
|
||||
[by](https://www.fullcontact.com)
|
||||
by
|
||||
[quite](http://open.mediaexpress.reuters.com/)
|
||||
[a few](https://rokt.com/) companies and
|
||||
a
|
||||
[few](https://rokt.com/) companies and
|
||||
individuals to build complex apps, many running to 50K lines of
|
||||
ClojureScript code, and beyond.
|
||||
|
||||
<img align="right" src="/images/scale-changes-everything.jpg?raw=true">
|
||||
|
||||
Scale changes everything. Frameworks
|
||||
**Scale changes everything.** Frameworks
|
||||
are just pesky overhead at small scale - measure them instead by how they help
|
||||
you tame the complexity of bigger apps, and in this regard re-frame has
|
||||
worked out well. Some have even praised it effusively.
|
||||
|
|
|
@ -70,11 +70,6 @@ going further (certainly read the first two):
|
|||
- [presentation (video)](http://www.infoq.com/presentations/ClojureScript-Javelin) by Alan Dipert (co-author of Hoplon)
|
||||
- [serious pants Elm thesis](https://www.seas.harvard.edu/sites/default/files/files/archived/Czaplicki.pdf)
|
||||
|
||||
And for the love of all that is good, please watch this terrific
|
||||
[StrangeLoop presentation ](https://www.youtube.com/watch?v=fU9hR3kiOK0) (40 mins). Watch what happens
|
||||
when you re-imagine a database as a stream!! Look at all the problems that are solved.
|
||||
Think about that: shared mutable state (the root of all evil),
|
||||
re-imagined as a stream!! Blew my socks off.
|
||||
|
||||
|
||||
### How Flow Happens In Reagent
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 13 KiB |
Loading…
Reference in New Issue