WEBVTT

1
00:00:00.120 --> 00:00:05.200
<v Speaker 1>So picture the scenario for a second. You are staring

2
00:00:05.280 --> 00:00:07.400
<v Speaker 1>at a blank screen on day one of a brand

3
00:00:07.440 --> 00:00:08.000
<v Speaker 1>new project.

4
00:00:08.119 --> 00:00:09.599
<v Speaker 2>Oh, the best feeling, right.

5
00:00:09.679 --> 00:00:13.240
<v Speaker 1>The architecture feels pristine, you are mapping out the logic.

6
00:00:13.359 --> 00:00:16.079
<v Speaker 1>Those first few features are just you know, flying out

7
00:00:16.079 --> 00:00:18.399
<v Speaker 1>the door. The boss is thrilled and you feel like

8
00:00:18.440 --> 00:00:19.640
<v Speaker 1>an absolute genius.

9
00:00:19.839 --> 00:00:23.239
<v Speaker 2>Yeah, it is the classic honeymoon phase of software development.

10
00:00:23.280 --> 00:00:26.920
<v Speaker 2>I mean, everything is clean because well, nothing is complex yet.

11
00:00:26.960 --> 00:00:30.000
<v Speaker 1>But then almost inevitably, you hit the complexity wall. It

12
00:00:30.079 --> 00:00:31.160
<v Speaker 1>just sneaks up on you.

13
00:00:31.440 --> 00:00:32.200
<v Speaker 2>It always does.

14
00:00:32.399 --> 00:00:35.399
<v Speaker 1>Suddenly, adding a simple check box to a screen takes

15
00:00:35.439 --> 00:00:38.600
<v Speaker 1>two entire weeks. The code that used to be elegant

16
00:00:38.759 --> 00:00:42.320
<v Speaker 1>is now this tangled, fragile mess of unmaintainable spaghetti.

17
00:00:42.439 --> 00:00:44.439
<v Speaker 2>Right like, you fix a bug in the payment gateway

18
00:00:44.719 --> 00:00:47.719
<v Speaker 2>and somehow it breaks the user profile picture.

19
00:00:47.600 --> 00:00:50.560
<v Speaker 1>Exactly, and development just grinds to a halt. You are

20
00:00:50.640 --> 00:00:53.159
<v Speaker 1>left pulling your hair out wondering where it all went wrong.

21
00:00:53.840 --> 00:00:57.159
<v Speaker 1>So today, for this deep dive, we are exploring a

22
00:00:57.280 --> 00:01:00.679
<v Speaker 1>radical paradigm shift that promises to be the antidote to

23
00:01:00.679 --> 00:01:02.600
<v Speaker 1>that exact universal nightmare.

24
00:01:02.840 --> 00:01:07.480
<v Speaker 2>Yeah, we are looking it away to fundamentally rethink how

25
00:01:07.519 --> 00:01:11.680
<v Speaker 2>we conquer software complexity, specifically in the realm of building

26
00:01:11.760 --> 00:01:13.159
<v Speaker 2>interactive systems.

27
00:01:12.799 --> 00:01:14.799
<v Speaker 1>And we are pulling our insights today from the book

28
00:01:14.879 --> 00:01:19.159
<v Speaker 1>Functional Reactive Programming by Steven Blackheath and Anthony Jones. Our

29
00:01:19.159 --> 00:01:22.359
<v Speaker 1>mission is to figure out how this concept functional reactive

30
00:01:22.359 --> 00:01:26.959
<v Speaker 1>programming or FRP, can tear down that complexity wall for good.

31
00:01:27.120 --> 00:01:28.519
<v Speaker 2>It's a big promise, it is.

32
00:01:28.799 --> 00:01:32.040
<v Speaker 1>Okay, let's unpack this. To understand the cure, we first

33
00:01:32.040 --> 00:01:35.760
<v Speaker 1>have to understand the disease. Why do our interactive apps

34
00:01:35.840 --> 00:01:38.000
<v Speaker 1>always devolve into spaghetti code?

35
00:01:38.319 --> 00:01:40.760
<v Speaker 2>Well, the authors argue that the disease is rooted in

36
00:01:40.799 --> 00:01:44.079
<v Speaker 2>the very foundation of how we handle events in almost

37
00:01:44.079 --> 00:01:47.959
<v Speaker 2>all interactive applications today, whether you are building a user interface,

38
00:01:48.040 --> 00:01:49.879
<v Speaker 2>a video game, a mobile.

39
00:01:49.599 --> 00:01:52.439
<v Speaker 1>App, basically anything we use on a daily basis.

40
00:01:52.079 --> 00:01:55.079
<v Speaker 2>Right, developers rely on something called the observer pattern. You

41
00:01:55.159 --> 00:01:58.079
<v Speaker 2>might know it as listeners or callbacks. It is by

42
00:01:58.120 --> 00:02:01.280
<v Speaker 2>far the dominant way to pass messages around in software.

43
00:02:01.359 --> 00:02:03.560
<v Speaker 1>So if I click a submit button on my screen,

44
00:02:03.959 --> 00:02:06.359
<v Speaker 1>there is a piece of code like a listener waiting

45
00:02:06.359 --> 00:02:08.759
<v Speaker 1>in the background for that click, which then triggers a

46
00:02:08.800 --> 00:02:12.439
<v Speaker 1>callback function to actually process the data. And I mean

47
00:02:12.560 --> 00:02:15.000
<v Speaker 1>on the surface that sounds like a totally logical way

48
00:02:15.039 --> 00:02:15.879
<v Speaker 1>to build software.

49
00:02:16.000 --> 00:02:19.800
<v Speaker 2>It does, and historically it was a massive improvement over

50
00:02:19.919 --> 00:02:23.599
<v Speaker 2>older methods. It allowed for looser coupling between different parts

51
00:02:23.599 --> 00:02:28.240
<v Speaker 2>of a program. But the authors identify what they call

52
00:02:28.319 --> 00:02:30.080
<v Speaker 2>the six plagues of listeners.

53
00:02:30.520 --> 00:02:31.560
<v Speaker 1>Six plagues.

54
00:02:31.639 --> 00:02:35.400
<v Speaker 2>Wow, Yeah, there are fundamental, unavoidable flaws in the observer

55
00:02:35.520 --> 00:02:37.840
<v Speaker 2>pattern that directly cause that complexity.

56
00:02:37.879 --> 00:02:39.879
<v Speaker 1>Wall, I really want to go through these because I

57
00:02:39.879 --> 00:02:41.919
<v Speaker 1>have a feeling anyone who has ever written a line

58
00:02:41.919 --> 00:02:43.759
<v Speaker 1>of code is going to feel seen right now.

59
00:02:43.879 --> 00:02:48.400
<v Speaker 2>Oh, absolutely so. The first plague is unpredictable order. If

60
00:02:48.439 --> 00:02:51.080
<v Speaker 2>you have a complex network of listeners all waiting for

61
00:02:51.159 --> 00:02:54.280
<v Speaker 2>various events, the order in which they actually receive those

62
00:02:54.319 --> 00:02:57.960
<v Speaker 2>events can depend entirely on the invisible, behind the scenes

63
00:02:58.039 --> 00:03:00.879
<v Speaker 2>order in which they were originally registered in the computer's memory.

64
00:03:00.960 --> 00:03:03.120
<v Speaker 1>Wait, so, if I'm building a dashboard and I have

65
00:03:03.280 --> 00:03:06.479
<v Speaker 1>a listener for a user logging in and another listener

66
00:03:06.479 --> 00:03:09.039
<v Speaker 1>for loading their profile picture, they might fire in a

67
00:03:09.080 --> 00:03:10.319
<v Speaker 1>completely random sequence.

68
00:03:10.360 --> 00:03:10.840
<v Speaker 2>Pretty much.

69
00:03:10.879 --> 00:03:14.240
<v Speaker 1>That makes me think of like a chaotic group text

70
00:03:14.280 --> 00:03:17.039
<v Speaker 1>thread where people have bad cell service and messages are

71
00:03:17.039 --> 00:03:19.360
<v Speaker 1>just arriving out of sync. You are trying to read

72
00:03:19.360 --> 00:03:22.599
<v Speaker 1>a conversation, but the punchline arrives before the setup.

73
00:03:23.080 --> 00:03:26.479
<v Speaker 2>That is a perfect mental model for the chaos. And

74
00:03:26.599 --> 00:03:29.039
<v Speaker 2>imagine if a new person is added to that group

75
00:03:29.080 --> 00:03:32.439
<v Speaker 2>chat late, they completely missed the original context.

76
00:03:32.599 --> 00:03:33.599
<v Speaker 1>Oh right.

77
00:03:33.719 --> 00:03:35.479
<v Speaker 2>In the book they call that the second plague the

78
00:03:35.520 --> 00:03:39.400
<v Speaker 2>missed first event. It is remarkably easy to accidentally trigger

79
00:03:39.439 --> 00:03:43.199
<v Speaker 2>an initialization event a millisecond before the specific listener is

80
00:03:43.240 --> 00:03:44.400
<v Speaker 2>actually registered to hear it.

81
00:03:44.639 --> 00:03:48.240
<v Speaker 1>Ah. The classic is this thing on bug. The system

82
00:03:48.360 --> 00:03:51.439
<v Speaker 1>just shouts its status into an empty room exactly.

83
00:03:51.759 --> 00:03:54.039
<v Speaker 2>It only gets worse from there. The third plague is

84
00:03:54.080 --> 00:03:57.960
<v Speaker 2>messi state because callbacks are just isolated reactions, They inherently

85
00:03:58.000 --> 00:04:00.599
<v Speaker 2>push you toward building traditional state machines keep track.

86
00:04:00.479 --> 00:04:02.599
<v Speaker 1>Of what happened, and as the app grows.

87
00:04:02.599 --> 00:04:05.360
<v Speaker 2>The human brain just cannot keep track of a massive

88
00:04:05.400 --> 00:04:08.199
<v Speaker 2>web of shifting states. Yes, too much. Then you add

89
00:04:08.199 --> 00:04:12.199
<v Speaker 2>the fourth plague, threading issues. The moment you try to

90
00:04:12.240 --> 00:04:15.879
<v Speaker 2>make all these overlapping listeners ThreadSafe so they can run simultaneously,

91
00:04:16.199 --> 00:04:18.399
<v Speaker 2>you run headfirst into deadlocks, or.

92
00:04:18.360 --> 00:04:21.000
<v Speaker 1>Two parts of your program are permanently waiting for each

93
00:04:21.000 --> 00:04:21.720
<v Speaker 1>other to finish.

94
00:04:21.839 --> 00:04:24.480
<v Speaker 2>Yeah, which usually results in the entire app just freezing.

95
00:04:24.639 --> 00:04:28.839
<v Speaker 1>Oh. Man, what about memory, Because in that group text analogy,

96
00:04:28.920 --> 00:04:31.279
<v Speaker 1>you eventually have people in the chat who haven't spoken

97
00:04:31.319 --> 00:04:34.240
<v Speaker 1>in three years, but are still getting every single notification.

98
00:04:34.519 --> 00:04:37.800
<v Speaker 2>That brings us perfectly to the fifth plague, leaking callbacks.

99
00:04:38.279 --> 00:04:41.560
<v Speaker 2>If a developer forgets to explicitly de register a listener

100
00:04:41.879 --> 00:04:45.399
<v Speaker 2>when a component is closed, that listener just stays alive

101
00:04:45.439 --> 00:04:46.920
<v Speaker 2>in the background memory forever.

102
00:04:47.120 --> 00:04:49.920
<v Speaker 1>So over time, your application just consumes more and more

103
00:04:50.000 --> 00:04:52.000
<v Speaker 1>RAM until it crashes bingo.

104
00:04:52.560 --> 00:04:55.920
<v Speaker 2>And finally, the sixth plague is accidental recursion.

105
00:04:56.160 --> 00:04:57.160
<v Speaker 1>Oh, that sounds bad.

106
00:04:57.360 --> 00:05:00.519
<v Speaker 2>It is the sequence in which you update local variables

107
00:05:00.519 --> 00:05:03.839
<v Speaker 2>and notify other listeners can easily cause an infinite loop

108
00:05:03.839 --> 00:05:06.720
<v Speaker 2>of updates if you aren't incredibly careful, like.

109
00:05:06.720 --> 00:05:09.399
<v Speaker 1>The dreaded infinite reply all email chain.

110
00:05:09.680 --> 00:05:13.480
<v Speaker 2>Yes, so, hearing all these plagues together, it is practically

111
00:05:13.480 --> 00:05:17.600
<v Speaker 2>impossible to piece together a true, reliable sequence of events

112
00:05:17.639 --> 00:05:18.439
<v Speaker 2>in a large app.

113
00:05:18.560 --> 00:05:21.720
<v Speaker 1>So this raises an important question, why do we tolerate this?

114
00:05:22.600 --> 00:05:26.920
<v Speaker 2>Well, the truth is all useful programs are fundamentally state machines.

115
00:05:27.319 --> 00:05:30.240
<v Speaker 2>They take inputs, they change state, and they produce outputs.

116
00:05:30.759 --> 00:05:33.040
<v Speaker 2>But as we just outlined, tracking the state of an

117
00:05:33.040 --> 00:05:36.160
<v Speaker 2>application through an invisible web of callbacks is a nightmare

118
00:05:36.240 --> 00:05:37.079
<v Speaker 2>for human cognition.

119
00:05:37.519 --> 00:05:39.720
<v Speaker 1>Right, so we need a completely different way to manage

120
00:05:39.759 --> 00:05:43.680
<v Speaker 1>state and that brings us to functional reactive programming. Yes,

121
00:05:44.000 --> 00:05:47.279
<v Speaker 1>but moving to FRP isn't just a matter of downloading

122
00:05:47.319 --> 00:05:49.680
<v Speaker 1>a new library and learning some new syntax, is it.

123
00:05:50.040 --> 00:05:52.839
<v Speaker 1>The book describes it as a full blown paradigm shift.

124
00:05:53.120 --> 00:05:55.519
<v Speaker 2>It really is. You cannot just sprinkle a little FRP

125
00:05:55.680 --> 00:05:57.680
<v Speaker 2>on top of your listener based code and expect the

126
00:05:57.680 --> 00:05:59.959
<v Speaker 2>plagues to vanish. You have to change how you think

127
00:06:00.040 --> 00:06:03.600
<v Speaker 2>about logic itself. Okay, we must move away from operational

128
00:06:03.600 --> 00:06:07.519
<v Speaker 2>thinking and embrace conceptual thinking, or, to use the industry terms,

129
00:06:07.800 --> 00:06:11.240
<v Speaker 2>moving from imperative programming to declarative programming.

130
00:06:11.439 --> 00:06:14.000
<v Speaker 1>I love how the book illustrates this shift. They use

131
00:06:14.000 --> 00:06:16.839
<v Speaker 1>a lasagna recipe, which is such a brilliant way to

132
00:06:16.959 --> 00:06:19.800
<v Speaker 1>break down a very abstract computer science concept.

133
00:06:19.879 --> 00:06:20.839
<v Speaker 2>It's a great analogy.

134
00:06:20.920 --> 00:06:23.759
<v Speaker 1>So let's look at the operational way first, the old way,

135
00:06:23.800 --> 00:06:26.959
<v Speaker 1>the way we usually code. It is a sequence of tedious,

136
00:06:27.160 --> 00:06:31.600
<v Speaker 1>micromanaged steps like heat the oil in a pan, fry

137
00:06:31.600 --> 00:06:35.360
<v Speaker 1>the onions until golden add ground beef and tomato simmer

138
00:06:35.439 --> 00:06:36.240
<v Speaker 1>for twenty minutes.

139
00:06:36.600 --> 00:06:39.120
<v Speaker 2>Right. And if you explain lasagna that way to someone

140
00:06:39.160 --> 00:06:41.480
<v Speaker 2>who has never seen or tasted it, they have no

141
00:06:41.560 --> 00:06:44.079
<v Speaker 2>idea what the final dish actually is until they finish

142
00:06:44.160 --> 00:06:45.720
<v Speaker 2>the grueling process of making it.

143
00:06:45.720 --> 00:06:48.079
<v Speaker 1>It is just a blind list of chores exactly.

144
00:06:48.439 --> 00:06:51.759
<v Speaker 2>But the conceptual way, the FRP way, flips that entirely

145
00:06:51.800 --> 00:06:54.120
<v Speaker 2>on its head. It defines what the thing is bathed

146
00:06:54.120 --> 00:06:55.639
<v Speaker 2>purely on its dependencies.

147
00:06:55.839 --> 00:06:59.279
<v Speaker 1>So the declarative recipe is simply lasagna is grated cheese

148
00:06:59.319 --> 00:07:03.079
<v Speaker 1>on cheese, on bolonnaise, on flat pasta baked right. And

149
00:07:03.079 --> 00:07:05.079
<v Speaker 1>what does Blannie say, Well, bolonese is a fried onion

150
00:07:05.120 --> 00:07:06.720
<v Speaker 1>mixed with ground beef and tomato.

151
00:07:07.120 --> 00:07:11.199
<v Speaker 2>Notice how that subtle shift fundamentally changes the programmer's burden.

152
00:07:12.079 --> 00:07:16.240
<v Speaker 2>In the operational recipe, the sequence is paramount. If you

153
00:07:16.319 --> 00:07:18.759
<v Speaker 2>tell the computer to add the cheese before it heats

154
00:07:18.839 --> 00:07:20.879
<v Speaker 2>the oil, you ruin the dish entirely.

155
00:07:20.959 --> 00:07:23.319
<v Speaker 1>You're just left with a burnt mess, exactly.

156
00:07:23.480 --> 00:07:27.000
<v Speaker 2>You, the programmer, carry the heavy mental weight of micromanaging

157
00:07:27.040 --> 00:07:29.120
<v Speaker 2>the exact timeline of events.

158
00:07:29.480 --> 00:07:31.560
<v Speaker 1>But in the conceptual recipe, I mean, I don't care

159
00:07:31.600 --> 00:07:34.319
<v Speaker 1>whether the cheese sauce is prepared before the bolonnaise or

160
00:07:34.399 --> 00:07:36.920
<v Speaker 1>after or at the exact same time on a different burner.

161
00:07:37.240 --> 00:07:41.480
<v Speaker 1>I am just mapping out the relationships the dependencies, Yes, exactly,

162
00:07:41.759 --> 00:07:43.519
<v Speaker 1>But I do have to push back here on behalf

163
00:07:43.560 --> 00:07:46.680
<v Speaker 1>of the listener. If I am not explicitly telling the

164
00:07:46.680 --> 00:07:49.360
<v Speaker 1>computer what sequence to do things in, how does the

165
00:07:49.360 --> 00:07:54.639
<v Speaker 1>machine actually know? Because a computer fundamentally executes instructions sequentially.

166
00:07:54.120 --> 00:07:55.920
<v Speaker 2>It does, and this is where the magic of the

167
00:07:55.959 --> 00:07:59.560
<v Speaker 2>FRP engine comes into play. Under the herd, it constructs

168
00:07:59.560 --> 00:08:03.560
<v Speaker 2>what computer scientists call a directed acyclic graph or a

169
00:08:03.639 --> 00:08:06.519
<v Speaker 2>dag okay, a dag Yeah. It looks at your conceptual

170
00:08:06.560 --> 00:08:11.279
<v Speaker 2>recipe and builds a literal mathematical map in memory of

171
00:08:11.319 --> 00:08:13.879
<v Speaker 2>how everything relates. It knows the Lasagna depends on the

172
00:08:13.879 --> 00:08:16.480
<v Speaker 2>Bolognaise and the Bolognese depends on the onions. Got it.

173
00:08:16.519 --> 00:08:19.920
<v Speaker 2>Then the engine performs a topological sort on that graph

174
00:08:20.199 --> 00:08:23.319
<v Speaker 2>to automatically figure out the perfect sequence of execution for you.

175
00:08:23.639 --> 00:08:26.639
<v Speaker 1>Wow, that is incredibly librating. So I just draw the

176
00:08:26.680 --> 00:08:30.639
<v Speaker 1>map and the FRP engine acts as the master chef,

177
00:08:30.800 --> 00:08:34.840
<v Speaker 1>guaranteeing that everything is processed in the correct natural order exactly.

178
00:08:35.639 --> 00:08:39.480
<v Speaker 2>Sequence bugs become mathematically impossible because you're no longer writing sequences.

179
00:08:39.960 --> 00:08:42.879
<v Speaker 1>If we connect this to the bigger picture, all FRP

180
00:08:43.039 --> 00:08:46.120
<v Speaker 1>code is conceptually just a flow of data. You are

181
00:08:46.159 --> 00:08:51.200
<v Speaker 1>transforming inputs into outputs without ever manually handling the timeline precisely. Okay,

182
00:08:51.240 --> 00:08:54.759
<v Speaker 1>So if we are mapping out dependencies instead of writing sequences,

183
00:08:55.240 --> 00:08:58.519
<v Speaker 1>what are the actual building blocks we are connecting? What

184
00:08:58.639 --> 00:09:00.960
<v Speaker 1>is our pasta and our cheese in the code?

185
00:09:01.120 --> 00:09:03.960
<v Speaker 2>In the FARP universe, everything is built on just two

186
00:09:04.000 --> 00:09:06.200
<v Speaker 2>fundamental data types, streams and cells.

187
00:09:06.360 --> 00:09:09.440
<v Speaker 1>Let's clearly define those because the entire paradigm rests on them.

188
00:09:09.639 --> 00:09:12.200
<v Speaker 2>Sure, so, think of a stream as a representation of

189
00:09:12.240 --> 00:09:15.039
<v Speaker 2>discrete events. It is a flow of data that only

190
00:09:15.080 --> 00:09:18.879
<v Speaker 2>exists instantaneously at the exact moment it fires. Okay. The

191
00:09:18.879 --> 00:09:21.240
<v Speaker 2>book gives a really great example of a Japanese board

192
00:09:21.240 --> 00:09:25.519
<v Speaker 2>game chat window. Imagine you have two buttons for canned messages.

193
00:09:25.919 --> 00:09:30.039
<v Speaker 2>One that says onnigaishimasu to politely greet your opponent, and

194
00:09:30.120 --> 00:09:31.320
<v Speaker 2>one that says thank you.

195
00:09:32.159 --> 00:09:34.799
<v Speaker 1>So clicking one of those buttons is a discrete event.

196
00:09:35.000 --> 00:09:36.919
<v Speaker 1>It happens in an instant sends a message, and then

197
00:09:36.960 --> 00:09:38.480
<v Speaker 1>it's gone. That is a.

198
00:09:38.440 --> 00:09:41.440
<v Speaker 2>Stream, You got it. The other data type is a cell.

199
00:09:41.960 --> 00:09:45.039
<v Speaker 2>A cell represents a value that changes over time, but

200
00:09:45.080 --> 00:09:47.279
<v Speaker 2>the golden rule of a cell is that it always

201
00:09:47.279 --> 00:09:49.960
<v Speaker 2>has a value. You can sample a cell at any

202
00:09:50.039 --> 00:09:52.879
<v Speaker 2>exact microsecond and it will give you its current state.

203
00:09:53.200 --> 00:09:55.679
<v Speaker 1>Like a text input field on that same board game

204
00:09:55.759 --> 00:09:58.440
<v Speaker 1>chat window. If I type I like FRP into the box,

205
00:09:58.519 --> 00:10:01.159
<v Speaker 1>the box always contains some of text, even if that

206
00:10:01.240 --> 00:10:04.639
<v Speaker 1>string is just empty space. Initially, the text updates as

207
00:10:04.679 --> 00:10:06.679
<v Speaker 1>I type, but the box itself is never in a

208
00:10:06.720 --> 00:10:10.559
<v Speaker 1>state of non existence. It represents the current ongoing state

209
00:10:10.600 --> 00:10:11.799
<v Speaker 1>of that UI element.

210
00:10:12.159 --> 00:10:16.879
<v Speaker 2>Precisely, to summarize the difference, streams model state changes. The

211
00:10:16.960 --> 00:10:21.039
<v Speaker 2>instantaneous events will sells model the state itself.

212
00:10:21.320 --> 00:10:23.759
<v Speaker 1>Here's where it gets really interesting, though, And I have

213
00:10:23.840 --> 00:10:27.039
<v Speaker 1>to push back on this cell concept because something doesn't

214
00:10:27.039 --> 00:10:30.879
<v Speaker 1>add up. If a cell represents a value that changes

215
00:10:30.960 --> 00:10:34.639
<v Speaker 1>over time, isn't that just a mutable variable wearing a

216
00:10:34.679 --> 00:10:38.879
<v Speaker 1>fancy disguise. Because anyone who has dabbled in functional programming

217
00:10:38.960 --> 00:10:42.000
<v Speaker 1>knows that mutable state, you know, variables that change is

218
00:10:42.039 --> 00:10:45.440
<v Speaker 1>considered the ultimate evil. It makes code unpredictable. How can

219
00:10:45.480 --> 00:10:48.360
<v Speaker 1>a system claim to be functional if it relies on

220
00:10:48.399 --> 00:10:49.279
<v Speaker 1>a changing cell?

221
00:10:49.600 --> 00:10:52.240
<v Speaker 2>You have hit on the central paradox of FRP, and

222
00:10:52.279 --> 00:10:56.080
<v Speaker 2>the authors actually acknowledge its tension directly. State mutation is

223
00:10:56.159 --> 00:11:00.240
<v Speaker 2>dangerous in pure functional programming, but event handling in the

224
00:11:00.240 --> 00:11:03.559
<v Speaker 2>real world is inherently stateful. You can't just pretend state

225
00:11:03.600 --> 00:11:06.039
<v Speaker 2>doesn't exist when a user is interacting with a screen.

226
00:11:06.519 --> 00:11:08.960
<v Speaker 2>So to solve this, the book uses this brilliant analogy

227
00:11:09.000 --> 00:11:09.879
<v Speaker 2>of Pandora's box.

228
00:11:10.080 --> 00:11:11.720
<v Speaker 1>Okay, walk us through Pandora's box.

229
00:11:11.759 --> 00:11:16.080
<v Speaker 2>In this context, FRP takes the inherent evil of mutable state,

230
00:11:16.600 --> 00:11:20.000
<v Speaker 2>chops it up into tiny pieces, and locks each piece

231
00:11:20.120 --> 00:11:25.159
<v Speaker 2>inside mathematically pure immutable containers. And those containers are your

232
00:11:25.200 --> 00:11:26.080
<v Speaker 2>streams and cells.

233
00:11:26.480 --> 00:11:28.399
<v Speaker 1>Oh, I think I see where this is going. The

234
00:11:28.440 --> 00:11:31.919
<v Speaker 1>container itself cannot be changed, even if the timeline of

235
00:11:32.000 --> 00:11:34.879
<v Speaker 1>value is flowing through, it represents a changing state.

236
00:11:35.440 --> 00:11:39.240
<v Speaker 2>That is the crucial distinction. You aren't mutating a variable

237
00:11:39.279 --> 00:11:41.679
<v Speaker 2>in place like you do in traditional code. You are

238
00:11:41.720 --> 00:11:43.960
<v Speaker 2>defining an immutable timeline of values.

239
00:11:44.000 --> 00:11:44.840
<v Speaker 1>Okay, that makes sense.

240
00:11:44.879 --> 00:11:47.559
<v Speaker 2>Because the stream or cell object itself is locked down

241
00:11:47.600 --> 00:11:51.039
<v Speaker 2>and pure, the engine can track it safely. The evil

242
00:11:51.120 --> 00:11:54.960
<v Speaker 2>is contained. You get the mathematical reliability of functional programming

243
00:11:55.320 --> 00:11:58.360
<v Speaker 2>while still being able to build a dynamic stateful application.

244
00:11:58.519 --> 00:12:00.000
<v Speaker 1>That's amazing, But keeping the.

245
00:12:00.039 --> 00:12:02.360
<v Speaker 2>Evil contained requires absolute discipline.

246
00:12:02.519 --> 00:12:04.720
<v Speaker 1>I assume you were referring to the no cheating rule

247
00:12:04.840 --> 00:12:05.759
<v Speaker 1>mentioned in the text.

248
00:12:05.840 --> 00:12:09.200
<v Speaker 2>Exactly to keep Pandora's box closed, every single function you

249
00:12:09.240 --> 00:12:12.279
<v Speaker 2>pass into your FRP engine must be referentially.

250
00:12:11.720 --> 00:12:15.840
<v Speaker 1>Transparent, meaning I cannot write a function that secretly reaches

251
00:12:15.919 --> 00:12:19.639
<v Speaker 1>outside of itself to read a global variable, or write

252
00:12:19.639 --> 00:12:21.639
<v Speaker 1>a file to the hard drive, or fire off a

253
00:12:21.720 --> 00:12:22.759
<v Speaker 1>rogue network request.

254
00:12:22.879 --> 00:12:25.720
<v Speaker 2>No hidden inputs, no hidden outputs. A function must look

255
00:12:26.000 --> 00:12:28.759
<v Speaker 2>solely at the data handed to it and return a result.

256
00:12:28.840 --> 00:12:30.960
<v Speaker 2>And if you don't do that, the moment you cheat

257
00:12:30.960 --> 00:12:34.799
<v Speaker 2>by modifying external state, you break the directed acyclic graph.

258
00:12:34.960 --> 00:12:37.480
<v Speaker 2>The end, you can no longer guarantee the sequence. Pandora's

259
00:12:37.519 --> 00:12:41.080
<v Speaker 2>box blasts open, and your code reverts right back to

260
00:12:41.120 --> 00:12:43.519
<v Speaker 2>the messy plagues of the observer pattern.

261
00:12:43.679 --> 00:12:47.799
<v Speaker 1>It is fascinating how strict constraints paradoxically give you total freedom.

262
00:12:48.039 --> 00:12:50.720
<v Speaker 1>Because you are physically prevented from cheating, you just stop

263
00:12:50.759 --> 00:12:53.840
<v Speaker 1>worrying about side effects. You can trust the math exactly.

264
00:12:53.960 --> 00:12:57.240
<v Speaker 1>So let's talk about how we actually combine these pure containers.

265
00:12:57.519 --> 00:13:00.840
<v Speaker 1>The book notes the entire FRP ecosystem and relies on

266
00:13:01.000 --> 00:13:03.320
<v Speaker 1>just ten primitive operations, just.

267
00:13:03.320 --> 00:13:08.200
<v Speaker 2>Ten foundational primitives things like map, merge, hole, snapshot lift.

268
00:13:08.679 --> 00:13:11.480
<v Speaker 2>By combining these ten tools, you can build software of

269
00:13:11.519 --> 00:13:12.559
<v Speaker 2>infinite complexity.

270
00:13:12.840 --> 00:13:15.879
<v Speaker 1>Let's look at the snapshot primitive first. The book's example

271
00:13:15.879 --> 00:13:18.399
<v Speaker 1>for this really clarified things for me. They build a

272
00:13:18.519 --> 00:13:19.919
<v Speaker 1>mock Latin translator.

273
00:13:20.039 --> 00:13:22.399
<v Speaker 2>Yeah, adding the suffix us to the end of every

274
00:13:22.480 --> 00:13:24.759
<v Speaker 2>word to sound falsely authoritative.

275
00:13:24.919 --> 00:13:28.320
<v Speaker 1>Exactly. So imagine building this. You have a text box

276
00:13:28.440 --> 00:13:31.279
<v Speaker 1>which is a cell because it holds ongoing state, and

277
00:13:31.320 --> 00:13:34.000
<v Speaker 1>you have a translate button, which is a stream because

278
00:13:34.120 --> 00:13:37.559
<v Speaker 1>clicking it is an instantaneous event. You can't just mash

279
00:13:37.639 --> 00:13:40.519
<v Speaker 1>a stream and a cell together. Instead, you use the

280
00:13:40.559 --> 00:13:44.879
<v Speaker 1>snapshot primitive. When the button stream fires, it snapshots the

281
00:13:44.919 --> 00:13:48.120
<v Speaker 1>exact value of the text cell at that specific millisecond,

282
00:13:48.559 --> 00:13:51.519
<v Speaker 1>runs it through your translation function, and spits out itanius

283
00:13:51.639 --> 00:13:53.320
<v Speaker 1>udiavus FRPs.

284
00:13:53.440 --> 00:13:54.279
<v Speaker 2>It's brilliant.

285
00:13:54.399 --> 00:13:56.600
<v Speaker 1>It is a flawless way to combine an event with

286
00:13:56.639 --> 00:13:58.200
<v Speaker 1>a state without worrying about.

287
00:13:57.960 --> 00:14:00.720
<v Speaker 2>Timing bugs, and that completely bypas as is the threading

288
00:14:00.720 --> 00:14:04.240
<v Speaker 2>issues we discussed earlier. But to truly understand the power

289
00:14:04.240 --> 00:14:07.360
<v Speaker 2>of FRP. We need to look at the merge primitive. Okay,

290
00:14:07.679 --> 00:14:12.080
<v Speaker 2>merge takes two separate streams and combines them into one unified.

291
00:14:11.679 --> 00:14:15.399
<v Speaker 1>Stream, which sounds incredibly simple until you realize that real

292
00:14:15.519 --> 00:14:18.320
<v Speaker 1>users trigger simultaneous events all the time.

293
00:14:18.360 --> 00:14:20.879
<v Speaker 2>All the time. So let's apply this to a real

294
00:14:20.919 --> 00:14:25.039
<v Speaker 2>world scenario from the book. Imagine you are building a

295
00:14:25.080 --> 00:14:29.200
<v Speaker 2>diagramming tool. You have a canvas showing a triangle and

296
00:14:29.279 --> 00:14:32.240
<v Speaker 2>an octagon. Okay, the business rules dictate that clicking an

297
00:14:32.279 --> 00:14:35.720
<v Speaker 2>object selects it, and clicking anywhere else on the canvas

298
00:14:35.919 --> 00:14:36.720
<v Speaker 2>de selects it.

299
00:14:36.879 --> 00:14:39.679
<v Speaker 1>So if the triangle is currently selected and my mouse

300
00:14:40.039 --> 00:14:42.600
<v Speaker 1>clicks the octagon, two logical things have to happen at

301
00:14:42.639 --> 00:14:44.399
<v Speaker 1>the exact same moment. I have to de select the

302
00:14:44.440 --> 00:14:47.279
<v Speaker 1>triangle and I have to select the octagon. In a

303
00:14:47.279 --> 00:14:51.559
<v Speaker 1>traditional listener setup, this is a massive race condition which

304
00:14:51.639 --> 00:14:56.360
<v Speaker 1>callback fires first. Does the UI momentarily show zero objects

305
00:14:56.399 --> 00:14:59.840
<v Speaker 1>selected or both objects selected before resolving.

306
00:15:00.279 --> 00:15:02.399
<v Speaker 2>In traditional code, you just cross your fingers and hope

307
00:15:02.399 --> 00:15:05.360
<v Speaker 2>the callbacks resolve in the order you intended. But FRP

308
00:15:05.519 --> 00:15:08.360
<v Speaker 2>handles this through explicit atomic transactions.

309
00:15:08.440 --> 00:15:10.320
<v Speaker 1>Atomic transaction, Yes, if.

310
00:15:10.240 --> 00:15:12.799
<v Speaker 2>Two events originate from the exact same root cause. In

311
00:15:12.799 --> 00:15:15.840
<v Speaker 2>this case, the single mouse click. The FRP engine groups

312
00:15:15.840 --> 00:15:20.159
<v Speaker 2>them together. They are mathematically simultaneous. The merge primitive actually

313
00:15:20.159 --> 00:15:23.159
<v Speaker 2>forces the programmer to provide a conflict resolution function.

314
00:15:23.440 --> 00:15:25.759
<v Speaker 1>Wait, so I literally have to write a rule that

315
00:15:25.879 --> 00:15:29.159
<v Speaker 1>says if a selection and a de selection happen in

316
00:15:29.200 --> 00:15:32.240
<v Speaker 1>the same transaction, here is exactly how you combine them.

317
00:15:32.320 --> 00:15:36.240
<v Speaker 2>You cannot even compile the code without explicitly stating how

318
00:15:36.240 --> 00:15:40.559
<v Speaker 2>to handle the collision. The engine demands clarity. Wow, Because

319
00:15:40.559 --> 00:15:43.879
<v Speaker 2>you define the logic upfront, there is no unpredictable order.

320
00:15:44.080 --> 00:15:48.039
<v Speaker 2>The timeline is guaranteed, and this mathematical guarantee of what

321
00:15:48.159 --> 00:15:52.000
<v Speaker 2>allows for the holy grail of software design, compositionality.

322
00:15:52.279 --> 00:15:55.720
<v Speaker 1>The book leans heavily on that term compositionality. Let's break

323
00:15:55.759 --> 00:15:57.759
<v Speaker 1>down what that actually means for a developer sitting at

324
00:15:57.759 --> 00:15:58.159
<v Speaker 1>their desk.

325
00:15:58.399 --> 00:16:02.000
<v Speaker 2>Compositionality means you can say free combined small, perfectly working

326
00:16:02.000 --> 00:16:06.159
<v Speaker 2>pieces of code to make bigger pieces of code indefinitely.

327
00:16:05.559 --> 00:16:06.960
<v Speaker 1>Which you can't always do normally.

328
00:16:07.120 --> 00:16:11.000
<v Speaker 2>No. In traditional listener based programming, combining two perfectly working

329
00:16:11.039 --> 00:16:14.559
<v Speaker 2>modules often creates brand new bugs just from how they're hidden.

330
00:16:14.559 --> 00:16:18.559
<v Speaker 2>Callbacks interact with each other an FRP because of referential

331
00:16:18.559 --> 00:16:22.480
<v Speaker 2>transparency and strict primitives like merge. If the small components work,

332
00:16:22.759 --> 00:16:25.960
<v Speaker 2>the massive system built from them is mathematically guaranteed to

333
00:16:26.000 --> 00:16:27.240
<v Speaker 2>work just as reliably.

334
00:16:27.480 --> 00:16:30.720
<v Speaker 1>So building a mock Latin translator or a diagram tool

335
00:16:30.840 --> 00:16:33.120
<v Speaker 1>is a great proof of concept. But how does this

336
00:16:33.159 --> 00:16:36.159
<v Speaker 1>paradigm hold up when the complexity scales? We want to

337
00:16:36.159 --> 00:16:38.360
<v Speaker 1>see this applied to industrial software.

338
00:16:38.559 --> 00:16:42.480
<v Speaker 2>Well. To demonstrate scale, the book walks the reader through

339
00:16:43.000 --> 00:16:47.600
<v Speaker 2>building the logic for a petrol pump stimulator entirely using FRP.

340
00:16:47.679 --> 00:16:50.519
<v Speaker 1>Functional reactive petroleum. I love the imagery here, and the

341
00:16:50.559 --> 00:16:53.000
<v Speaker 1>book is very specific about the setup too. You have

342
00:16:53.399 --> 00:16:58.519
<v Speaker 1>three distinct fuel nozzles, strawberry, lime, and kerosene.

343
00:16:58.600 --> 00:17:02.240
<v Speaker 2>An interesting flavor selection petrol station, but it serves the

344
00:17:02.240 --> 00:17:05.440
<v Speaker 2>example well. A petrol pump seems straightforward until you map

345
00:17:05.519 --> 00:17:08.279
<v Speaker 2>out the overlapping states. You have the three nozzles, three

346
00:17:08.279 --> 00:17:11.039
<v Speaker 2>different fuel prices. You have a flow meter physically pulsing

347
00:17:11.079 --> 00:17:14.200
<v Speaker 2>as fuels delivered. You have a display tracking total dollars

348
00:17:14.200 --> 00:17:16.839
<v Speaker 2>and other tracking total leaders. And you have a keypad

349
00:17:16.880 --> 00:17:19.200
<v Speaker 2>where a user can punch in a preset dollar limit.

350
00:17:19.480 --> 00:17:21.640
<v Speaker 2>So the pump automatically stops itself.

351
00:17:21.359 --> 00:17:23.960
<v Speaker 1>If I were writing this as a traditional state machine,

352
00:17:24.440 --> 00:17:27.519
<v Speaker 1>tracking all of that would instantly devolve into a nightmare

353
00:17:27.599 --> 00:17:31.720
<v Speaker 1>of nested if then statements like if the strawberry nozzle

354
00:17:31.759 --> 00:17:34.640
<v Speaker 1>is lifted and the flow meter pulses, check if the

355
00:17:34.640 --> 00:17:37.799
<v Speaker 1>preset limit is reached, but only if the limit isn't zero,

356
00:17:38.000 --> 00:17:41.440
<v Speaker 1>and make sure the line nozzle isn't also lifted. It

357
00:17:41.880 --> 00:17:44.440
<v Speaker 1>is the definition of spaghetti code, it really is.

358
00:17:44.680 --> 00:17:48.119
<v Speaker 2>But an FRP you abandon the sequence of checks. You

359
00:17:48.160 --> 00:17:50.839
<v Speaker 2>write it as a continuous flow of data. The listing

360
00:17:50.839 --> 00:17:54.519
<v Speaker 2>of the strawberry or kerosene nozzles, those are instantaneous events,

361
00:17:54.559 --> 00:17:57.240
<v Speaker 2>so they are modeled as streams. Okay, the changing fuel

362
00:17:57.240 --> 00:18:00.920
<v Speaker 2>prices those told values over time, so they are cells.

363
00:18:01.039 --> 00:18:04.119
<v Speaker 1>Well, what about the keypad limit or tracking the accumulating

364
00:18:04.160 --> 00:18:06.640
<v Speaker 1>total of fuel pumped? How do I track a running

365
00:18:06.640 --> 00:18:09.599
<v Speaker 1>total without creating a mutable variable that I constantly update.

366
00:18:09.640 --> 00:18:12.400
<v Speaker 1>Doesn't defining a total based on its previous total cause

367
00:18:12.440 --> 00:18:13.960
<v Speaker 1>that accidental recursion.

368
00:18:13.599 --> 00:18:17.240
<v Speaker 2>Plague In a standard listeners system, Yes, updating a variable

369
00:18:17.240 --> 00:18:20.079
<v Speaker 2>based on itself would trigger an endless loop of callbacks.

370
00:18:20.599 --> 00:18:23.279
<v Speaker 2>But FRP solves this with a mechanism called a cell loop,

371
00:18:23.720 --> 00:18:25.400
<v Speaker 2>combined with a subtle delay step.

372
00:18:25.480 --> 00:18:27.759
<v Speaker 1>How does that actually work into the hood without crashing

373
00:18:28.039 --> 00:18:28.680
<v Speaker 1>The cell.

374
00:18:28.480 --> 00:18:32.039
<v Speaker 2>Loop essentially tells the FRP engine to calculate the new

375
00:18:32.119 --> 00:18:35.319
<v Speaker 2>value of this cell for the current transaction, look at

376
00:18:35.359 --> 00:18:38.640
<v Speaker 2>the value of this cell from the previous transaction plus

377
00:18:38.680 --> 00:18:40.039
<v Speaker 2>the new input from the flow meter.

378
00:18:40.279 --> 00:18:41.200
<v Speaker 1>AH.

379
00:18:41.319 --> 00:18:45.720
<v Speaker 2>Because the engine updates everything atomically in distinct steps, it

380
00:18:45.880 --> 00:18:49.759
<v Speaker 2>safely handles that forward reference. It breaks the infinite loop

381
00:18:50.000 --> 00:18:53.200
<v Speaker 2>by separating the timeline into discrete frames.

382
00:18:52.799 --> 00:18:58.079
<v Speaker 1>So you express the entire petrol pump strictly as mathematical relationships.

383
00:18:58.440 --> 00:19:01.960
<v Speaker 1>Total dollars is simply e well to leaders delivered multiplied

384
00:19:02.000 --> 00:19:04.799
<v Speaker 1>by the active fuel price. The data just flows through

385
00:19:04.839 --> 00:19:07.359
<v Speaker 1>the application logic like fuel thrill pipe.

386
00:19:07.039 --> 00:19:09.880
<v Speaker 2>And you entirely avoid the state machine nightmare. When the

387
00:19:09.880 --> 00:19:12.480
<v Speaker 2>product manager asks you to add a new feature like

388
00:19:12.559 --> 00:19:15.640
<v Speaker 2>making the preset dollar limit automatically slow down the fuel

389
00:19:15.640 --> 00:19:17.039
<v Speaker 2>flow before it stops.

390
00:19:16.839 --> 00:19:19.319
<v Speaker 1>You just add a new dependency line to your graph exactly.

391
00:19:19.359 --> 00:19:22.119
<v Speaker 2>You don't have to rewrite a fragile sequence of fifty callbacks.

392
00:19:22.400 --> 00:19:25.200
<v Speaker 1>So what does this all mean for you the listener?

393
00:19:25.680 --> 00:19:28.880
<v Speaker 1>We've covered a massive amount of ground today. We started

394
00:19:28.880 --> 00:19:32.400
<v Speaker 1>with the complexity wall, the inevitable breakdown of software. We

395
00:19:32.519 --> 00:19:36.799
<v Speaker 1>explored the six plagues of event driven programming, the misted events,

396
00:19:36.920 --> 00:19:39.839
<v Speaker 1>the messi states, the memory leaks, yeah, all of it,

397
00:19:40.119 --> 00:19:43.640
<v Speaker 1>and we've seen how functional reactive programming offers an escape route.

398
00:19:43.799 --> 00:19:48.440
<v Speaker 2>It offers a rigorously mathematical, declarative escape row. By locking

399
00:19:48.480 --> 00:19:51.880
<v Speaker 2>the inherent chaos of state inside pure containers, streams, and

400
00:19:52.000 --> 00:19:56.160
<v Speaker 2>cells and only interacting with them using ten strict primitives,

401
00:19:56.559 --> 00:19:59.200
<v Speaker 2>we gain the superpower of true compositionality.

402
00:19:59.640 --> 00:20:02.640
<v Speaker 1>Whether if you are actively coding JABA applications or you

403
00:20:02.680 --> 00:20:05.640
<v Speaker 1>are just a professional trying to navigate a world overloaded

404
00:20:05.640 --> 00:20:09.240
<v Speaker 1>with increasingly complex systems, shifting your mental model is an

405
00:20:09.240 --> 00:20:14.119
<v Speaker 1>incredible tool. Moving your brain from operational sequences desperately micromanaging

406
00:20:14.160 --> 00:20:17.920
<v Speaker 1>every step of a process, to conceptual dependencies. Defining how

407
00:20:17.960 --> 00:20:21.279
<v Speaker 1>things fundamentally relate to one another is a massive advantage

408
00:20:21.279 --> 00:20:22.400
<v Speaker 1>for cutting through the noise.

409
00:20:22.799 --> 00:20:25.279
<v Speaker 2>It forces you to clearly define what a system is,

410
00:20:25.400 --> 00:20:27.799
<v Speaker 2>rather than frantically trying to control what a system does

411
00:20:27.839 --> 00:20:29.720
<v Speaker 2>at every single millisecond.

412
00:20:29.200 --> 00:20:30.960
<v Speaker 1>Which brings me to a final thought for you, tom

413
00:20:30.960 --> 00:20:35.240
<v Speaker 1>all over, if functional reactive programming forces us to strictly

414
00:20:35.279 --> 00:20:39.720
<v Speaker 1>define relationships and dependencies, to prevent chaos in our software.

415
00:20:40.440 --> 00:20:43.160
<v Speaker 1>What would happen if we applied this declarative mindset to

416
00:20:43.200 --> 00:20:44.480
<v Speaker 1>our human organizations?

417
00:20:44.640 --> 00:20:46.759
<v Speaker 2>Oh, that is quite the conceptual leap.

418
00:20:47.079 --> 00:20:49.400
<v Speaker 1>Think about it. We have all been trapped in that

419
00:20:49.519 --> 00:20:52.880
<v Speaker 1>chaotic group text thread or that office email chain that

420
00:20:52.920 --> 00:20:56.720
<v Speaker 1>acts exactly like a broken listener pattern, messages out of order,

421
00:20:57.160 --> 00:21:00.039
<v Speaker 1>teams working off outdated states, infinite reply.

422
00:20:59.759 --> 00:21:01.759
<v Speaker 2>All sounds like my Tuesday?

423
00:21:01.960 --> 00:21:05.640
<v Speaker 1>Right? What if we redefine our office workflows not as rigid,

424
00:21:05.759 --> 00:21:10.680
<v Speaker 1>micromanaged sequences of operational tasks, but as pure dependent data streams.

425
00:21:11.359 --> 00:21:14.440
<v Speaker 1>Could applying this declarative mindset finally cure the six plagues

426
00:21:14.480 --> 00:21:17.440
<v Speaker 1>of modern office communication. Is definitely something to think about

427
00:21:17.440 --> 00:21:19.599
<v Speaker 1>the next time you hit a complexity wall, whether that

428
00:21:19.680 --> 00:21:22.000
<v Speaker 1>wall is in your codebase or just in your inbox.
