WEBVTT

1
00:00:00.120 --> 00:00:03.120
<v Speaker 1>You know, usually when we think about building a massive

2
00:00:03.200 --> 00:00:08.000
<v Speaker 1>digital platform, something that handles millions of requests a second,

3
00:00:08.759 --> 00:00:14.400
<v Speaker 1>we picture this incredibly complex, chaotic web of moving parts.

4
00:00:14.519 --> 00:00:18.920
<v Speaker 1>Oh absolutely, Like I always imagine a giant, sprawling restaurant kitchen.

5
00:00:18.920 --> 00:00:23.359
<v Speaker 1>You have thousands of cooks constantly shouting tweaking recipes on

6
00:00:23.399 --> 00:00:26.359
<v Speaker 1>the fly, grabbing ingredients out of each other's hands, you know,

7
00:00:26.440 --> 00:00:29.480
<v Speaker 1>just to keep the whole dinner service from collapsing, right, And.

8
00:00:29.440 --> 00:00:33.640
<v Speaker 2>That kitchen analogy highlights the exact danger developers face at scale,

9
00:00:33.640 --> 00:00:36.920
<v Speaker 2>which is race conditions. Yeah, because when two chefs reach

10
00:00:37.000 --> 00:00:39.280
<v Speaker 2>for the salt a millisecond apart and try to use

11
00:00:39.320 --> 00:00:42.719
<v Speaker 2>it simultaneously, I mean, the entire system just crashes. It

12
00:00:42.759 --> 00:00:45.320
<v Speaker 2>really feels like the bigger the architecture gets, the more

13
00:00:45.359 --> 00:00:47.039
<v Speaker 2>inherently fragile it should be.

14
00:00:47.520 --> 00:00:49.159
<v Speaker 1>But then you look under the hood of the apps

15
00:00:49.200 --> 00:00:51.560
<v Speaker 1>you probably use just this morning. I mean, if you

16
00:00:51.640 --> 00:00:55.479
<v Speaker 1>scroll through Twitter, ordered Nuber, watch Netflix, or bought something

17
00:00:55.520 --> 00:00:59.039
<v Speaker 1>on Amazon recently, you haven't been interacting with a chaotic,

18
00:00:59.119 --> 00:00:59.920
<v Speaker 1>fragile kitchen.

19
00:01:00.280 --> 00:01:01.399
<v Speaker 2>No, not at all.

20
00:01:01.479 --> 00:01:05.680
<v Speaker 1>You've been interacting with systems scaled using these remarkably stable,

21
00:01:06.120 --> 00:01:10.280
<v Speaker 1>rigidly disciplined principles running on the Java virtual machine.

22
00:01:09.920 --> 00:01:13.040
<v Speaker 2>And that stability. It actually came out of a painful

23
00:01:13.200 --> 00:01:17.560
<v Speaker 2>industry wide realization because for decades the software world relied

24
00:01:17.640 --> 00:01:20.640
<v Speaker 2>heavily on object oriented programming.

25
00:01:20.200 --> 00:01:23.159
<v Speaker 1>Like Java or C sharp, Python exactly.

26
00:01:23.519 --> 00:01:28.359
<v Speaker 2>Those languages established the bedrock of enterprise software. But as

27
00:01:28.560 --> 00:01:31.840
<v Speaker 2>our digital world just exploded in scale, we hit this

28
00:01:32.079 --> 00:01:34.680
<v Speaker 2>massive wall with concurrency.

29
00:01:34.040 --> 00:01:36.000
<v Speaker 1>Meaning handling tons of users.

30
00:01:35.680 --> 00:01:40.200
<v Speaker 2>At once right, handling millions of simultaneous users in traditional OOP,

31
00:01:40.680 --> 00:01:45.159
<v Speaker 2>it required a nightmare of threadlocking and synchronization. We desperately

32
00:01:45.159 --> 00:01:46.799
<v Speaker 2>needed a different approach.

33
00:01:46.359 --> 00:01:48.640
<v Speaker 1>Which is the core mission of our deep dives. Today

34
00:01:49.040 --> 00:01:51.519
<v Speaker 1>we are exploring the world of functional programming and a

35
00:01:51.599 --> 00:01:54.599
<v Speaker 1>language called Scala, using our source material on how to

36
00:01:54.599 --> 00:01:57.400
<v Speaker 1>build applications with it. Yeah, we're going to unpack exactly

37
00:01:57.400 --> 00:02:00.280
<v Speaker 1>how the biggest tech companies keep the Internet running without

38
00:02:00.319 --> 00:02:02.480
<v Speaker 1>their servers, you know, constantly catching on fire.

39
00:02:02.560 --> 00:02:03.760
<v Speaker 2>It's a fascinating shift.

40
00:02:04.040 --> 00:02:06.159
<v Speaker 1>So Scala enters the picture in two thousand and one,

41
00:02:06.239 --> 00:02:09.280
<v Speaker 1>created by Martin O. Durski, and the text describes it

42
00:02:09.319 --> 00:02:13.199
<v Speaker 1>as this post functional multi paradigm language.

43
00:02:13.439 --> 00:02:17.280
<v Speaker 2>Yeah, it bridges a massive gap, but to understand how

44
00:02:17.319 --> 00:02:20.960
<v Speaker 2>it solves modern concurrency problems. We actually have to look backward. Okay,

45
00:02:21.120 --> 00:02:23.599
<v Speaker 2>functional programming's roots. They go all the way back to

46
00:02:23.639 --> 00:02:28.520
<v Speaker 2>mathematical abstractions from the nineteen thirties, specifically this formal system

47
00:02:28.560 --> 00:02:30.080
<v Speaker 2>called lambda calculus.

48
00:02:30.280 --> 00:02:31.759
<v Speaker 1>Wait the nineteen thirties.

49
00:02:31.479 --> 00:02:35.000
<v Speaker 2>Yeah, the nineteen thirties, And the very first language implementation

50
00:02:35.080 --> 00:02:38.319
<v Speaker 2>of these ideas was Lisp back in the nineteen fifties.

51
00:02:38.479 --> 00:02:41.120
<v Speaker 1>That's wild. I mean, I always assume functional programming was

52
00:02:41.159 --> 00:02:44.479
<v Speaker 1>this modern, cutting edge Silicon Valley trend. But you're telling

53
00:02:44.479 --> 00:02:46.879
<v Speaker 1>me it's practically ancient history and computer science.

54
00:02:47.039 --> 00:02:49.960
<v Speaker 2>It is. But back in the nineteen fifties, maintaining the

55
00:02:50.039 --> 00:02:56.479
<v Speaker 2>pure immutable state required by functional programming was incredibly expensive computationally.

56
00:02:55.919 --> 00:02:57.479
<v Speaker 1>Like, the machines just couldn't handle it right.

57
00:02:57.520 --> 00:03:00.240
<v Speaker 2>Computers just didn't have the memory or the processing power

58
00:03:00.319 --> 00:03:03.680
<v Speaker 2>to do it efficiently. But today, well, hardware has finally

59
00:03:03.680 --> 00:03:06.360
<v Speaker 2>caught up to the math. I see, those math based

60
00:03:06.400 --> 00:03:09.520
<v Speaker 2>principles from the fifties are now what power the most

61
00:03:09.560 --> 00:03:14.120
<v Speaker 2>modern infrastructure. We have massive big data tools like Hadoop

62
00:03:14.199 --> 00:03:17.000
<v Speaker 2>or Spark. They're built entirely around map.

63
00:03:16.840 --> 00:03:19.000
<v Speaker 1>Reduce, which is a functional concept.

64
00:03:18.599 --> 00:03:22.159
<v Speaker 2>Literally, a functional programming concept. We've taken pure academic math

65
00:03:22.199 --> 00:03:24.719
<v Speaker 2>and applied it to modern web scale traffic.

66
00:03:24.800 --> 00:03:28.719
<v Speaker 1>Okay, so we have this beautiful nineteen thirties mathematical purity.

67
00:03:29.240 --> 00:03:32.120
<v Speaker 1>But purity doesn't survive in the methi reality of modern

68
00:03:32.159 --> 00:03:35.400
<v Speaker 1>web traffic unless it has an absolute workhourse of an

69
00:03:35.400 --> 00:03:37.879
<v Speaker 1>engine to run on. That's right, and that's the compromise

70
00:03:37.960 --> 00:03:39.919
<v Speaker 1>skull I had to make. It runs on the JVM.

71
00:03:40.159 --> 00:03:43.319
<v Speaker 1>So it's like taking the aerodynamic ultra light chassis of

72
00:03:43.360 --> 00:03:46.599
<v Speaker 1>a Formula one car and bolting it directly onto the

73
00:03:46.680 --> 00:03:48.960
<v Speaker 1>undercarriage of a massive diesel freight train.

74
00:03:49.240 --> 00:03:50.400
<v Speaker 2>I love that analogy.

75
00:03:50.520 --> 00:03:52.439
<v Speaker 1>You get the cutting edge design, but you also get

76
00:03:52.479 --> 00:03:55.199
<v Speaker 1>the unstoppable, heavy duty momentum of the track.

77
00:03:55.360 --> 00:03:58.280
<v Speaker 2>Yeah, and that is the engineering pragmatism that made Skala

78
00:03:58.280 --> 00:04:02.639
<v Speaker 2>a huge success. Tethering's Gala to the JVM provides massive

79
00:04:02.719 --> 00:04:06.319
<v Speaker 2>immediate leverage. Also, you get native access to the entire

80
00:04:06.439 --> 00:04:11.479
<v Speaker 2>existing Java ecosystem, all those frameworks, enterprise library, security tools

81
00:04:11.479 --> 00:04:14.400
<v Speaker 2>that developers have spent the last twenty years building. Yeah,

82
00:04:14.520 --> 00:04:16.279
<v Speaker 2>Scala can interact with them natively.

83
00:04:16.600 --> 00:04:18.439
<v Speaker 1>I still have to push back a little here, though.

84
00:04:18.480 --> 00:04:24.279
<v Speaker 1>Sure if functional programming is this massive evolution from object

85
00:04:24.319 --> 00:04:28.639
<v Speaker 1>oriented programming. Why not just build a totally new runtime

86
00:04:28.759 --> 00:04:34.240
<v Speaker 1>environment from scratch. Why tether this sleek f one car

87
00:04:34.480 --> 00:04:36.720
<v Speaker 1>to legacy infrastructure.

88
00:04:36.959 --> 00:04:39.920
<v Speaker 2>It really just comes down to operational leverage. The JVM

89
00:04:40.040 --> 00:04:43.279
<v Speaker 2>is entirely battle tested by web scale companies. It has

90
00:04:43.319 --> 00:04:45.439
<v Speaker 2>proven it won't break when a million people click a

91
00:04:45.439 --> 00:04:47.600
<v Speaker 2>button at the exact same time, and more importantly, your

92
00:04:47.639 --> 00:04:51.040
<v Speaker 2>IT and DevOps teams they already know how to deploy, monitor,

93
00:04:51.079 --> 00:04:52.600
<v Speaker 2>and scale JVM applications.

94
00:04:52.720 --> 00:04:55.120
<v Speaker 1>Ah, so there's no learning curve for the operation side.

95
00:04:55.160 --> 00:04:57.639
<v Speaker 2>Exactly, if you introduce a completely new language with a

96
00:04:57.639 --> 00:05:00.160
<v Speaker 2>completely new run time, you force a company to been

97
00:05:00.279 --> 00:05:03.240
<v Speaker 2>millions of dollars rebuilding their entire deployment pipeline.

98
00:05:03.240 --> 00:05:04.240
<v Speaker 1>That makes a lot of sense.

99
00:05:04.279 --> 00:05:07.720
<v Speaker 2>With Scala, a company's operations team can run the application

100
00:05:07.839 --> 00:05:11.160
<v Speaker 2>exactly the same way they run legacy Java apps. Plus

101
00:05:11.319 --> 00:05:14.040
<v Speaker 2>Scala code can call Java code and vice versa.

102
00:05:14.600 --> 00:05:17.160
<v Speaker 1>So you aren't forcing an enterprise to just throw away

103
00:05:17.199 --> 00:05:21.279
<v Speaker 1>twenty years of legacy code just to modernize their concurrent processing.

104
00:05:21.480 --> 00:05:21.720
<v Speaker 2>Right.

105
00:05:22.199 --> 00:05:25.279
<v Speaker 1>Okay, that makes perfect sense. But since Scala runs on

106
00:05:25.319 --> 00:05:28.959
<v Speaker 1>the exact same engine as Java, the difference isn't the

107
00:05:29.000 --> 00:05:32.800
<v Speaker 1>machine itself. The transition we're talking about today is entirely

108
00:05:32.800 --> 00:05:36.120
<v Speaker 1>about the mindset of the developer driving it, and it.

109
00:05:36.079 --> 00:05:39.519
<v Speaker 2>Requires a radical shift. You're moving from imperative programming to

110
00:05:39.639 --> 00:05:40.839
<v Speaker 2>declarative programming.

111
00:05:40.879 --> 00:05:43.720
<v Speaker 1>I get the declarative mindset in theory, you know, telling

112
00:05:43.720 --> 00:05:45.920
<v Speaker 1>the system what I want to accomplish, not how to

113
00:05:46.000 --> 00:05:49.279
<v Speaker 1>do it. Yes, But mechanically, if I take away a

114
00:05:49.319 --> 00:05:53.759
<v Speaker 1>developer's ability to use imperative tools like for loops and

115
00:05:53.800 --> 00:05:57.439
<v Speaker 1>STANDARDI fel statements that mutate variables, aren't I just crippling

116
00:05:57.480 --> 00:05:59.959
<v Speaker 1>their toolkit? How does Scala compensate for them?

117
00:06:00.160 --> 00:06:03.879
<v Speaker 2>Well, you aren't crippling the toolkit. You're elevating the abstraction.

118
00:06:03.480 --> 00:06:04.519
<v Speaker 1>Elevating the extraction.

119
00:06:04.600 --> 00:06:04.920
<v Speaker 2>Yeah.

120
00:06:05.000 --> 00:06:05.199
<v Speaker 1>Right.

121
00:06:05.480 --> 00:06:11.199
<v Speaker 2>Imperative programming involves micromanaging the computer's state. You use statements

122
00:06:11.279 --> 00:06:15.000
<v Speaker 2>to manually dictate the sequence of operations. Update this counter,

123
00:06:15.240 --> 00:06:18.160
<v Speaker 2>move this pointer, check this condition, very step by step

124
00:06:18.439 --> 00:06:23.879
<v Speaker 2>exactly declarative programming, specifically, in a functional paradigm, it focuses

125
00:06:24.040 --> 00:06:27.199
<v Speaker 2>on composing expressions. Okay, Instead of a for loop that

126
00:06:27.319 --> 00:06:31.240
<v Speaker 2>mutates a counter variable, you use recursive structures and higher

127
00:06:31.360 --> 00:06:36.240
<v Speaker 2>order functions like map, filter or reduce. Those functions transform

128
00:06:36.319 --> 00:06:39.560
<v Speaker 2>a collection of data into a new collection without ever

129
00:06:39.639 --> 00:06:41.160
<v Speaker 2>altering the original.

130
00:06:41.120 --> 00:06:43.319
<v Speaker 1>And a big part of that shift is tackling what

131
00:06:43.399 --> 00:06:47.920
<v Speaker 1>the architecture documentation calls the ultimate villain in software design,

132
00:06:48.120 --> 00:06:49.319
<v Speaker 1>shared mutable state.

133
00:06:49.439 --> 00:06:52.439
<v Speaker 2>Oh yeah, shared mutable state is basically the root cause

134
00:06:52.480 --> 00:06:55.560
<v Speaker 2>of almost every major concurrency bug in existence.

135
00:06:55.720 --> 00:06:56.079
<v Speaker 1>Wow.

136
00:06:56.279 --> 00:06:59.360
<v Speaker 2>It's essentially a global variable that multiple different functions or

137
00:06:59.399 --> 00:07:02.279
<v Speaker 2>threads have direct access to, and they can modify it

138
00:07:02.319 --> 00:07:03.279
<v Speaker 2>at any given moment.

139
00:07:03.480 --> 00:07:06.759
<v Speaker 1>Returning to our restaurant kitchen, shared mutable state is having

140
00:07:06.879 --> 00:07:10.399
<v Speaker 1>ten different chefs standing around a single pot of soup. Yes, exactly,

141
00:07:10.600 --> 00:07:14.319
<v Speaker 1>One chef adds salt, another unexpectedly swaps out the chicken

142
00:07:14.399 --> 00:07:17.560
<v Speaker 1>broth for beef broth. Another turns the heat up to boiling,

143
00:07:17.879 --> 00:07:20.560
<v Speaker 1>and none of them are communicating, which is a disaster,

144
00:07:20.720 --> 00:07:23.560
<v Speaker 1>total chaos. When the soup finally reaches the customer, it's

145
00:07:23.680 --> 00:07:26.720
<v Speaker 1>ruined and you have absolutely no idea which chef destroyed

146
00:07:26.759 --> 00:07:29.560
<v Speaker 1>it or at what specific millisecond the error occurred.

147
00:07:29.639 --> 00:07:32.800
<v Speaker 2>And that lack of traceability is the true nightmare of

148
00:07:32.920 --> 00:07:36.879
<v Speaker 2>shared mutable state. It makes systems incredibly difficult to scale.

149
00:07:37.040 --> 00:07:40.959
<v Speaker 2>I can imagine refactoring the codebase becomes terrifying because you

150
00:07:41.000 --> 00:07:43.680
<v Speaker 2>can never trust the local method. You have to trace

151
00:07:43.800 --> 00:07:46.920
<v Speaker 2>every single function across the entire program that might touch

152
00:07:47.000 --> 00:07:49.720
<v Speaker 2>that global variable. Just to understand the logic.

153
00:07:49.560 --> 00:07:51.199
<v Speaker 1>That sounds exhausting, it is.

154
00:07:51.240 --> 00:07:54.839
<v Speaker 2>Functional programming avoids this entirely by ensuring state is kept

155
00:07:54.920 --> 00:07:56.120
<v Speaker 2>local and isolated.

156
00:07:56.319 --> 00:07:59.600
<v Speaker 1>So in the ft kitchen, every chef gets their own ingredients,

157
00:07:59.600 --> 00:08:02.639
<v Speaker 1>their own private cutting board, and a strict recipe that

158
00:08:02.759 --> 00:08:06.920
<v Speaker 1>absolutely cannot be altered mid cook. Precisely which brings us

159
00:08:06.920 --> 00:08:09.879
<v Speaker 1>to the actual rules of this new kitchen. The core

160
00:08:10.000 --> 00:08:14.240
<v Speaker 1>pillars of functional programming. The biggest one, the absolute bedrock

161
00:08:14.319 --> 00:08:16.439
<v Speaker 1>of this philosophy is immutability.

162
00:08:16.800 --> 00:08:19.680
<v Speaker 2>Yeah, and immutability simply means that once a value is

163
00:08:19.680 --> 00:08:22.879
<v Speaker 2>assigned to a variable, it can never ever be changed.

164
00:08:22.959 --> 00:08:24.120
<v Speaker 2>It is locked in memory.

165
00:08:24.560 --> 00:08:26.959
<v Speaker 1>But wait, if I can never change you variable, how

166
00:08:26.959 --> 00:08:30.639
<v Speaker 1>does my application actually process data? Like if a user

167
00:08:30.959 --> 00:08:34.399
<v Speaker 1>updates their profile picture and their profile object is immutable,

168
00:08:34.679 --> 00:08:35.840
<v Speaker 1>how do they get a new picture?

169
00:08:36.120 --> 00:08:41.159
<v Speaker 2>So you replace state mutation with discipline state discipline state right.

170
00:08:41.240 --> 00:08:44.720
<v Speaker 2>Instead of overwriting the existing profile object with the new picture,

171
00:08:45.159 --> 00:08:48.039
<v Speaker 2>your function creates a brand new instance of the profile

172
00:08:48.080 --> 00:08:51.879
<v Speaker 2>object that contains the new picture while preserving the old one.

173
00:08:52.039 --> 00:08:54.320
<v Speaker 2>You leave the original data completely alone.

174
00:08:54.360 --> 00:08:57.240
<v Speaker 1>But wouldn't that use a massive amount of memory just

175
00:08:57.399 --> 00:08:59.240
<v Speaker 1>constantly creating copies of everything.

176
00:08:59.519 --> 00:09:02.679
<v Speaker 2>It would if it were literally copying everything, But Scala

177
00:09:02.799 --> 00:09:06.639
<v Speaker 2>uses highly optimized structural sharing under the hood. Oh, when

178
00:09:06.679 --> 00:09:10.039
<v Speaker 2>you create that new profile object, it actually shares references

179
00:09:10.039 --> 00:09:13.039
<v Speaker 2>to all the unchanged data like the username and email

180
00:09:13.039 --> 00:09:14.000
<v Speaker 2>from the original object.

181
00:09:14.080 --> 00:09:14.559
<v Speaker 1>That's clever.

182
00:09:14.919 --> 00:09:17.960
<v Speaker 2>Yeah, it only allocates new memory for the piece that changed,

183
00:09:18.600 --> 00:09:21.679
<v Speaker 2>and the operational payoff for this is massive because there

184
00:09:21.679 --> 00:09:25.480
<v Speaker 2>are no side effects. Your code is parallel by nature.

185
00:09:25.320 --> 00:09:28.600
<v Speaker 1>Because multiple threads can read that data at the exact

186
00:09:28.600 --> 00:09:31.200
<v Speaker 1>same time without locking each other out.

187
00:09:31.399 --> 00:09:36.200
<v Speaker 2>Yes, you completely eliminate the need for thread synchronization locks.

188
00:09:36.840 --> 00:09:42.159
<v Speaker 2>Your program can run incredibly fast concurrently across dozens of processors.

189
00:09:41.840 --> 00:09:44.600
<v Speaker 1>Because no function is ever waiting to see if another

190
00:09:44.639 --> 00:09:49.200
<v Speaker 1>function is currently mutating the data exactly. It mathematically eliminates

191
00:09:49.200 --> 00:09:50.559
<v Speaker 1>the traffic jams in the system.

192
00:09:50.679 --> 00:09:51.360
<v Speaker 2>It really does.

193
00:09:51.480 --> 00:09:53.480
<v Speaker 1>So that brings us to how we actually manipulate this

194
00:09:53.480 --> 00:09:57.320
<v Speaker 1>immutable data. The functions themselves. In functional programming, they get

195
00:09:57.320 --> 00:10:00.360
<v Speaker 1>special treatment. We hear the terms first class function and

196
00:10:00.440 --> 00:10:02.559
<v Speaker 1>higher order functions thrown around constantly.

197
00:10:02.840 --> 00:10:05.440
<v Speaker 2>Yeah, and treating functions as first class citizens. Means the

198
00:10:05.480 --> 00:10:08.039
<v Speaker 2>programming language treats a function exactly the same way it

199
00:10:08.039 --> 00:10:11.039
<v Speaker 2>treats an integer or a string. Okay, you can assign

200
00:10:11.080 --> 00:10:13.679
<v Speaker 2>a function to a variable. You can pass a function

201
00:10:13.720 --> 00:10:16.840
<v Speaker 2>as an argument into another function. You can even return

202
00:10:16.879 --> 00:10:18.600
<v Speaker 2>a function as the result of an operation.

203
00:10:19.000 --> 00:10:21.120
<v Speaker 1>So they aren't just rigid script sitting on a server.

204
00:10:21.639 --> 00:10:25.000
<v Speaker 1>They're fluid pieces of data you can pass around your architecture.

205
00:10:25.200 --> 00:10:27.720
<v Speaker 2>Right, and that leads to higher order functions. These are

206
00:10:27.720 --> 00:10:30.399
<v Speaker 2>functions that take other functions as parameters.

207
00:10:30.559 --> 00:10:31.000
<v Speaker 1>Got it.

208
00:10:31.039 --> 00:10:36.639
<v Speaker 2>This enables incredibly powerful techniques like currying and partial functions.

209
00:10:36.679 --> 00:10:38.240
<v Speaker 1>Okay, currying, let's unpack that.

210
00:10:38.559 --> 00:10:41.279
<v Speaker 2>Currying is a mathematical technique where you take a function

211
00:10:41.320 --> 00:10:44.559
<v Speaker 2>that requires multiple parameters and you transform it into a

212
00:10:44.600 --> 00:10:48.279
<v Speaker 2>sequence of chain functions where each function takes only a

213
00:10:48.320 --> 00:10:49.200
<v Speaker 2>single argument.

214
00:10:49.360 --> 00:10:51.960
<v Speaker 1>Okay, I need a concrete example of that. Why would

215
00:10:52.000 --> 00:10:55.519
<v Speaker 1>I want to break a perfectly good multi parameter function

216
00:10:55.960 --> 00:10:58.480
<v Speaker 1>into a chain of single argument functions.

217
00:10:58.679 --> 00:11:02.519
<v Speaker 2>Well, imagine you have a function that queries a secure database.

218
00:11:03.159 --> 00:11:07.440
<v Speaker 2>It requires three arguments, an authentication token, the database endpoint,

219
00:11:07.559 --> 00:11:09.080
<v Speaker 2>and the actual query payload.

220
00:11:09.120 --> 00:11:09.759
<v Speaker 1>Siple enough.

221
00:11:09.919 --> 00:11:12.600
<v Speaker 2>Instead of passing all three arguments, every single. Time a

222
00:11:12.679 --> 00:11:16.559
<v Speaker 2>UI component requests data, currying allows you to basically bake

223
00:11:16.639 --> 00:11:19.960
<v Speaker 2>in the authentication token. Once that applications start up, you

224
00:11:20.039 --> 00:11:22.639
<v Speaker 2>pass the token in and it returns a new function

225
00:11:22.840 --> 00:11:26.639
<v Speaker 2>that only requires the endpoint and payload. Then you can

226
00:11:26.679 --> 00:11:29.279
<v Speaker 2>bake in the end point, returning yet another new function

227
00:11:29.320 --> 00:11:30.360
<v Speaker 2>that only needs the payload.

228
00:11:30.480 --> 00:11:33.480
<v Speaker 1>Oh wow, So I can pass that final single argument

229
00:11:33.519 --> 00:11:37.159
<v Speaker 1>function down to my front end UI components exactly, and

230
00:11:37.200 --> 00:11:41.080
<v Speaker 1>the UI just passes the query payload totally unaware of

231
00:11:41.120 --> 00:11:45.240
<v Speaker 1>the complex authentication or endpoint routing happening behind the scenes.

232
00:11:45.480 --> 00:11:48.440
<v Speaker 1>You're building customized single purpose tools on the fly.

233
00:11:48.720 --> 00:11:52.720
<v Speaker 2>It creates incredible modularity. It's heavily utilized in pure functional

234
00:11:52.759 --> 00:11:56.519
<v Speaker 2>languages like Haskell and Skoalar provides native support to build

235
00:11:56.559 --> 00:11:58.000
<v Speaker 2>these pipelines effortlessly.

236
00:11:58.360 --> 00:12:00.559
<v Speaker 1>This is where the architecture really starts to click for me.

237
00:12:01.039 --> 00:12:03.200
<v Speaker 1>But here's the piece of the puzzle that initially threw

238
00:12:03.240 --> 00:12:03.519
<v Speaker 1>me off.

239
00:12:03.600 --> 00:12:04.080
<v Speaker 2>What's up.

240
00:12:04.399 --> 00:12:07.840
<v Speaker 1>Scalar relies on a statically type system, A strong type system.

241
00:12:08.279 --> 00:12:12.039
<v Speaker 1>My instinct says that rigid, strict typing means more boilerplate,

242
00:12:12.159 --> 00:12:15.799
<v Speaker 1>more rules, and inevitably more testing to make sure everything aligns.

243
00:12:15.840 --> 00:12:18.440
<v Speaker 1>A lot of people think that, yet the documentation makes

244
00:12:18.440 --> 00:12:21.679
<v Speaker 1>this wild claim. A strong type system actually forces you

245
00:12:21.720 --> 00:12:22.559
<v Speaker 1>to write fewer.

246
00:12:22.320 --> 00:12:27.320
<v Speaker 2>Tests, and it does because Skala is statically typed. You're

247
00:12:27.639 --> 00:12:30.919
<v Speaker 2>shifting the burden of validation from run time tests back

248
00:12:30.919 --> 00:12:35.159
<v Speaker 2>to compile time. Okay, the compiler essentially becomes your strictest

249
00:12:35.279 --> 00:12:38.000
<v Speaker 2>editor in your first line of defense. Oh so well,

250
00:12:38.039 --> 00:12:41.919
<v Speaker 2>in a dynamically typed language like JavaScript or Python, you

251
00:12:42.000 --> 00:12:45.440
<v Speaker 2>might write a function that expects a user's age as

252
00:12:45.480 --> 00:12:49.080
<v Speaker 2>an integer and a separate service accidentally passes the word

253
00:12:49.159 --> 00:12:52.720
<v Speaker 2>thirty as a string. Right, the program will accept it,

254
00:12:52.759 --> 00:12:55.440
<v Speaker 2>and it might not crash until it's actually running live

255
00:12:55.519 --> 00:12:58.559
<v Speaker 2>in production and tries to run math on a word.

256
00:12:58.679 --> 00:13:02.320
<v Speaker 1>Which is exactly why to developers in dynamic languages spend

257
00:13:02.440 --> 00:13:06.039
<v Speaker 1>hours writing massive suites of unit tests just to verify.

258
00:13:06.159 --> 00:13:08.320
<v Speaker 1>You know, is this number? Is this a string? Please

259
00:13:08.360 --> 00:13:09.559
<v Speaker 1>handle this gracefully, right.

260
00:13:09.879 --> 00:13:12.559
<v Speaker 2>But in a strong type language like Scala, you define

261
00:13:12.559 --> 00:13:14.200
<v Speaker 2>the exact type upfront in.

262
00:13:14.159 --> 00:13:15.840
<v Speaker 1>The function signature, so it's locked in.

263
00:13:16.120 --> 00:13:18.440
<v Speaker 2>If that function demands an integer type and you try

264
00:13:18.480 --> 00:13:20.600
<v Speaker 2>to pass it a string of texts, the compiler simply

265
00:13:20.639 --> 00:13:23.399
<v Speaker 2>refuses to build the application. It won't let you make

266
00:13:23.440 --> 00:13:25.960
<v Speaker 2>that basic routing mistake, you don't have to write a

267
00:13:26.000 --> 00:13:28.720
<v Speaker 2>test checking if the input is an integer, because it

268
00:13:28.759 --> 00:13:32.039
<v Speaker 2>is mathematically impossible for the wrong data type to enter

269
00:13:32.080 --> 00:13:34.919
<v Speaker 2>that function in the first place. The compiler catches the

270
00:13:35.000 --> 00:13:37.360
<v Speaker 2>error before the program ever executes.

271
00:13:37.039 --> 00:13:39.919
<v Speaker 1>And that leads directly into another core concept you see

272
00:13:39.960 --> 00:13:43.320
<v Speaker 1>constantly in functional architecture, referential transparency.

273
00:13:43.480 --> 00:13:47.919
<v Speaker 2>Yes, referential transparency is the ultimate result of combining immutability

274
00:13:47.919 --> 00:13:51.159
<v Speaker 2>with strict types. Okay, it means that any function call

275
00:13:51.200 --> 00:13:54.600
<v Speaker 2>can be seamlessly replaced by its output value without changing

276
00:13:54.600 --> 00:13:55.879
<v Speaker 2>the behavior of the program.

277
00:13:56.240 --> 00:13:59.879
<v Speaker 1>Break that down mechanically. Why does that matter computationally?

278
00:14:00.159 --> 00:14:03.440
<v Speaker 2>Think of it like a math equation. If x equals five,

279
00:14:03.600 --> 00:14:06.840
<v Speaker 2>and why equals x plus two, you can confidently just

280
00:14:06.879 --> 00:14:09.639
<v Speaker 2>replace x with five. Everywhere you know the answer is

281
00:14:09.679 --> 00:14:13.879
<v Speaker 2>always seven. But in imperative programming, a background thread might

282
00:14:13.919 --> 00:14:17.440
<v Speaker 2>have mutated x to equal ten right before why was calculated?

283
00:14:17.480 --> 00:14:22.799
<v Speaker 2>You can't trust the variable unpredictable exactly because Scala enforces immutability.

284
00:14:23.039 --> 00:14:26.120
<v Speaker 2>A function called calculate tax given the input one hundred,

285
00:14:26.240 --> 00:14:28.840
<v Speaker 2>will always unequivocally return ten.

286
00:14:28.840 --> 00:14:30.360
<v Speaker 1>Because nothing else can mess with it.

287
00:14:30.639 --> 00:14:34.480
<v Speaker 2>Right, Because it relies on no external mutable state. The

288
00:14:34.559 --> 00:14:38.000
<v Speaker 2>system can safely cache that result ten across one thousand

289
00:14:38.039 --> 00:14:39.320
<v Speaker 2>different servers.

290
00:14:38.919 --> 00:14:42.519
<v Speaker 1>So you don't have to waste CPU cycles constantly recalculating

291
00:14:42.519 --> 00:14:45.360
<v Speaker 1>it or checking if the global tax rate variable changed

292
00:14:45.399 --> 00:14:48.919
<v Speaker 1>in the background. That cuts out massive amounts of compute

293
00:14:48.919 --> 00:14:49.639
<v Speaker 1>time at scale.

294
00:14:49.879 --> 00:14:54.720
<v Speaker 2>Yeah, the code essentially becomes its own reliable mathematical documentation.

295
00:14:54.879 --> 00:14:59.840
<v Speaker 2>You can parallelize and cache aggressively, which is the secret

296
00:15:00.080 --> 00:15:03.120
<v Speaker 2>to scaling applications to millions of users.

297
00:15:03.200 --> 00:15:06.480
<v Speaker 1>Okay, so we've established the philosophy. We have our disciplined

298
00:15:06.720 --> 00:15:10.399
<v Speaker 1>immutable kitchen where chefs pass around first class functions and

299
00:15:10.440 --> 00:15:13.120
<v Speaker 1>the compiler acts like a straight head chef, checking every

300
00:15:13.240 --> 00:15:14.080
<v Speaker 1>ingredient at the door.

301
00:15:14.200 --> 00:15:15.440
<v Speaker 2>That's a great summary, but.

302
00:15:15.440 --> 00:15:18.159
<v Speaker 1>Let's look at the actual reality the code. Comparing Java

303
00:15:18.240 --> 00:15:19.679
<v Speaker 1>to Scala side by side.

304
00:15:19.799 --> 00:15:21.600
<v Speaker 2>The best place to start that comparison is in the

305
00:15:21.639 --> 00:15:23.879
<v Speaker 2>interactive shell, the r epl.

306
00:15:23.679 --> 00:15:25.879
<v Speaker 1>Right, the read evil, print and loop. Because if I

307
00:15:25.919 --> 00:15:27.960
<v Speaker 1>want to write a standard Java application to test a

308
00:15:28.000 --> 00:15:30.480
<v Speaker 1>quick piece of logic, I have to configure a whole

309
00:15:30.519 --> 00:15:31.440
<v Speaker 1>project environment.

310
00:15:31.519 --> 00:15:32.159
<v Speaker 2>It's a hassle.

311
00:15:32.440 --> 00:15:35.480
<v Speaker 1>But with Scala, you just open your terminal type Scala

312
00:15:35.720 --> 00:15:38.759
<v Speaker 1>and you drop straight into an interactive loop. You type

313
00:15:38.759 --> 00:15:42.360
<v Speaker 1>of command, it evaluates, it prints the result, and waits

314
00:15:42.360 --> 00:15:43.200
<v Speaker 1>for the next input.

315
00:15:43.399 --> 00:15:46.679
<v Speaker 2>It creates an incredibly fast feedback loop for developers. You

316
00:15:46.720 --> 00:15:52.000
<v Speaker 2>can test complex functional pipelines without compiling an entire enterprise application.

317
00:15:51.639 --> 00:15:52.799
<v Speaker 1>In slight way.

318
00:15:53.039 --> 00:15:56.399
<v Speaker 2>Yeah, but when we look at formal application structure, the

319
00:15:56.559 --> 00:16:00.759
<v Speaker 2>verbosity of Java compared to the conciseness of Scala is stark.

320
00:16:01.159 --> 00:16:04.240
<v Speaker 1>It really is. The documentation gives a great side by

321
00:16:04.279 --> 00:16:07.960
<v Speaker 1>side Hello World showdown. In Java, printing a simple phrase

322
00:16:07.960 --> 00:16:10.600
<v Speaker 1>to the screen requires about six lines of code. You

323
00:16:10.600 --> 00:16:12.639
<v Speaker 1>have to define your package to find a public class,

324
00:16:12.879 --> 00:16:17.200
<v Speaker 1>write out the incredibly formal method, signature of public static void, mainstream, brackets, arcs,

325
00:16:17.360 --> 00:16:20.440
<v Speaker 1>and finally call system dot out dot print.

326
00:16:20.360 --> 00:16:23.399
<v Speaker 2>In it's an immense amount of ceremony for a simple action.

327
00:16:23.360 --> 00:16:26.080
<v Speaker 1>Right, and in Scala, achieving the exact same result takes

328
00:16:26.120 --> 00:16:29.240
<v Speaker 1>three lines. You write object hello world, extends app, open

329
00:16:29.240 --> 00:16:32.200
<v Speaker 1>your bracket, write print on Hello World, and close it.

330
00:16:32.600 --> 00:16:37.360
<v Speaker 2>Yeah. By extending that app trait, Scala completely abstracts away

331
00:16:37.440 --> 00:16:41.200
<v Speaker 2>the need for the developer to define that massive main method.

332
00:16:41.519 --> 00:16:42.799
<v Speaker 2>It's built into the language.

333
00:16:42.799 --> 00:16:46.720
<v Speaker 1>It's so clean, but there's a specific keyword you just used.

334
00:16:47.000 --> 00:16:51.440
<v Speaker 1>That signifies a massive architectural difference. You said object, Hello world,

335
00:16:51.600 --> 00:16:52.919
<v Speaker 1>not class Hello World.

336
00:16:53.039 --> 00:16:56.480
<v Speaker 2>Ah. Yes, this is a crucial distinction in maintaining a

337
00:16:56.519 --> 00:17:00.919
<v Speaker 2>discipline state. In Scala. Simply using the key word object

338
00:17:01.000 --> 00:17:04.359
<v Speaker 2>instead of class automatically creates a singleton pattern at the

339
00:17:04.400 --> 00:17:05.119
<v Speaker 2>language level.

340
00:17:05.200 --> 00:17:07.279
<v Speaker 1>And just to clarify the mechanics for a second, a

341
00:17:07.319 --> 00:17:10.200
<v Speaker 1>singleton is a design pattern used when you only ever

342
00:17:10.240 --> 00:17:13.720
<v Speaker 1>want one single instance of an object to exist across

343
00:17:13.799 --> 00:17:17.079
<v Speaker 1>the entire system, exactly, things like database connection pools or

344
00:17:17.200 --> 00:17:21.359
<v Speaker 1>configuration managers. But doing this safely in Java is notoriously difficult.

345
00:17:21.440 --> 00:17:24.319
<v Speaker 2>Oh, building a thread safe singleton in Java requires a

346
00:17:24.400 --> 00:17:25.480
<v Speaker 2>nightmare of boilerplate.

347
00:17:25.680 --> 00:17:25.960
<v Speaker 1>Really.

348
00:17:26.000 --> 00:17:28.079
<v Speaker 2>Oh yeah, You have to write a private constructor so

349
00:17:28.160 --> 00:17:31.640
<v Speaker 2>other classes can't instantiate it. You need a static instance variable,

350
00:17:31.680 --> 00:17:34.079
<v Speaker 2>You have to write a get instance method. And that's

351
00:17:34.119 --> 00:17:36.799
<v Speaker 2>just the start, right, Because if you are in a

352
00:17:36.880 --> 00:17:40.480
<v Speaker 2>multi threaded environment, you have to implement double checked locking

353
00:17:40.720 --> 00:17:45.559
<v Speaker 2>with synchronization blocks just to ensure two threads don't accidentally

354
00:17:45.640 --> 00:17:49.480
<v Speaker 2>create two instances at the exact same millisecond. Wow, it

355
00:17:49.559 --> 00:17:53.720
<v Speaker 2>takes over a dozen lines of complex, error prone code.

356
00:17:53.400 --> 00:17:56.039
<v Speaker 1>And in Scarlight you just type the word object. That's it.

357
00:17:56.559 --> 00:18:00.640
<v Speaker 2>The language provides the thread safe abstraction implicitly. It handles

358
00:18:00.680 --> 00:18:03.359
<v Speaker 2>the lazy initialization safely under the hood.

359
00:18:03.559 --> 00:18:04.160
<v Speaker 1>That's amazing.

360
00:18:04.240 --> 00:18:06.920
<v Speaker 2>When you multiply that reduction in boiler played across a

361
00:18:06.960 --> 00:18:10.359
<v Speaker 2>million line code base, the cognitive load on the developers

362
00:18:10.480 --> 00:18:14.079
<v Speaker 2>drops dramatically. Writing less code mathematically means you have a

363
00:18:14.119 --> 00:18:16.279
<v Speaker 2>smaller surface area for bugs to hide.

364
00:18:16.519 --> 00:18:19.119
<v Speaker 1>Let's close out the code segment with the absolute basics

365
00:18:19.119 --> 00:18:22.279
<v Speaker 1>of how variables are handled. Because we said immutability is

366
00:18:22.279 --> 00:18:25.200
<v Speaker 1>the core of functional programming, but we also know Scala

367
00:18:25.279 --> 00:18:29.200
<v Speaker 1>is multi paradigm. Does the language physically force you to

368
00:18:29.400 --> 00:18:31.119
<v Speaker 1>only use immutable variables.

369
00:18:31.200 --> 00:18:34.200
<v Speaker 2>It doesn't force you, but it's design deeply favors it.

370
00:18:34.559 --> 00:18:37.319
<v Speaker 2>You have two options for declaring variables in scalavarn val.

371
00:18:37.640 --> 00:18:40.839
<v Speaker 2>If you use var, you are creating a mutable reference

372
00:18:40.880 --> 00:18:42.599
<v Speaker 2>of value you can overwrite later.

373
00:18:42.640 --> 00:18:44.079
<v Speaker 1>The dreaded mutable state.

374
00:18:44.319 --> 00:18:46.599
<v Speaker 2>Well, it's only dreaded if you allow it to escape

375
00:18:46.599 --> 00:18:47.440
<v Speaker 2>your local scope.

376
00:18:47.880 --> 00:18:48.400
<v Speaker 1>Fair point.

377
00:18:49.000 --> 00:18:52.359
<v Speaker 2>Sometimes mutating a local counter inside a highly isolated function

378
00:18:52.480 --> 00:18:56.759
<v Speaker 2>is just more computationally efficient. But the standard default in

379
00:18:56.799 --> 00:19:00.160
<v Speaker 2>Scala is val, and val means when you dec fila

380
00:19:00.319 --> 00:19:04.079
<v Speaker 2>of variable. With val, you are creating a strictly immutable reference.

381
00:19:04.480 --> 00:19:07.160
<v Speaker 2>Once it points to an object, it can never be reassigned.

382
00:19:07.400 --> 00:19:07.599
<v Speaker 1>Never.

383
00:19:07.759 --> 00:19:10.440
<v Speaker 2>The compiler will literally throw an error and halt the

384
00:19:10.480 --> 00:19:12.200
<v Speaker 2>build if you attempt to reassign it.

385
00:19:12.279 --> 00:19:16.240
<v Speaker 1>So it's building the guardrails directly into the syntax exactly. So,

386
00:19:16.559 --> 00:19:19.799
<v Speaker 1>looking at this entire journey from nineteen thirty's math to

387
00:19:19.960 --> 00:19:23.519
<v Speaker 1>compiling immutable variables on the JVM, what does this all

388
00:19:23.559 --> 00:19:24.799
<v Speaker 1>mean for you, the listener?

389
00:19:24.920 --> 00:19:25.839
<v Speaker 2>It's a big question.

390
00:19:26.200 --> 00:19:28.839
<v Speaker 1>This deep dive wasn't just about learning a new programming

391
00:19:28.880 --> 00:19:32.720
<v Speaker 1>syntax or comparing the spelling of Java versus Skala. What

392
00:19:32.799 --> 00:19:35.680
<v Speaker 1>we're really talking about is a profound philosophy of predictability.

393
00:19:36.039 --> 00:19:39.720
<v Speaker 2>Yeah, when you eliminate shared mutable state, lock down your

394
00:19:39.759 --> 00:19:43.079
<v Speaker 2>values with immutability, and let a strict compiler catch your

395
00:19:43.119 --> 00:19:47.440
<v Speaker 2>logical errors before runtime, you remove the chaos from the system.

396
00:19:47.599 --> 00:19:48.519
<v Speaker 1>You totally do.

397
00:19:48.559 --> 00:19:52.920
<v Speaker 2>You shift from hoping your application works to mathematically proving

398
00:19:52.960 --> 00:19:53.640
<v Speaker 2>it works.

399
00:19:54.240 --> 00:19:58.720
<v Speaker 1>And that predictability is exactly what provides the unbelievable horsepower

400
00:19:58.799 --> 00:20:03.519
<v Speaker 1>required to the world's biggest digital platform smoothly, absolutely, but

401
00:20:03.599 --> 00:20:06.960
<v Speaker 1>beyond the server room, the core concepts of functional programming

402
00:20:07.319 --> 00:20:11.119
<v Speaker 1>actually offer an incredibly interesting lens for how we process

403
00:20:11.160 --> 00:20:12.640
<v Speaker 1>information in our own lives.

404
00:20:13.039 --> 00:20:15.839
<v Speaker 2>It really is a fascinating parallel think about how we

405
00:20:15.920 --> 00:20:18.680
<v Speaker 2>operate as human beings in the modern world. Okay, we

406
00:20:18.720 --> 00:20:22.319
<v Speaker 2>have dozens of browser tabs open, our phones are constantly buzzing.

407
00:20:22.640 --> 00:20:24.799
<v Speaker 2>We're trying to retain a thought for an upcoming meeting

408
00:20:24.799 --> 00:20:26.680
<v Speaker 2>while actively listening to a conversation.

409
00:20:26.880 --> 00:20:28.039
<v Speaker 1>Guilty is charged.

410
00:20:28.200 --> 00:20:31.079
<v Speaker 2>We are constantly allowing external side effects to interrupt our

411
00:20:31.119 --> 00:20:35.680
<v Speaker 2>local functions. We essentially live our lives as one giant, chaotic,

412
00:20:35.839 --> 00:20:37.039
<v Speaker 2>shared mutable state.

413
00:20:37.279 --> 00:20:41.799
<v Speaker 1>We are constantly getting our internal variables overwritten by distractions.

414
00:20:41.359 --> 00:20:44.359
<v Speaker 2>Which leaves us with a compelling final thought, love that

415
00:20:45.039 --> 00:20:49.759
<v Speaker 2>if enforcing strict constraints like absolute immutability and zero side

416
00:20:49.759 --> 00:20:53.640
<v Speaker 2>effects is the exact mechanism that allows our computing systems

417
00:20:53.680 --> 00:20:58.319
<v Speaker 2>to become infinitely more scalable, resilient, and creative, how might

418
00:20:58.359 --> 00:21:02.880
<v Speaker 2>we apply that to our own own daily workflows. If

419
00:21:02.920 --> 00:21:06.160
<v Speaker 2>we treated our current task as a pure function, blocking

420
00:21:06.160 --> 00:21:09.480
<v Speaker 2>out all external inputs, refusing to let our attention be

421
00:21:09.640 --> 00:21:14.480
<v Speaker 2>mutated by an incoming notification, could adopting a functional mindset

422
00:21:14.559 --> 00:21:18.400
<v Speaker 2>actually free us from our own mental bugs and cognitive overload.

423
00:21:18.119 --> 00:21:20.799
<v Speaker 1>Shutting down the chaotic kitchen in our own minds. Every

424
00:21:20.839 --> 00:21:23.400
<v Speaker 1>chef gets their own cutting board exactly. It is definitely

425
00:21:23.400 --> 00:21:25.359
<v Speaker 1>something to experiment with the next time you sit down

426
00:21:25.359 --> 00:21:27.839
<v Speaker 1>to focus. Thank you so much for joining us on

427
00:21:27.880 --> 00:21:29.640
<v Speaker 1>this deep dive today. We hope it gave you a

428
00:21:29.680 --> 00:21:33.319
<v Speaker 1>totally new perspective on the invisible architecture running the modern world.

429
00:21:33.720 --> 00:21:36.880
<v Speaker 1>Keep exploring, keep questioning the systems running behind the scenes,

430
00:21:37.200 --> 00:21:38.519
<v Speaker 1>and we will catch you next time.
