WEBVTT

1
00:00:00.120 --> 00:00:05.400
<v Speaker 1>You know, when you think about structural engineering, like say

2
00:00:05.719 --> 00:00:09.160
<v Speaker 1>building a suspension bridge or I don't know, a massive skyscraper,

3
00:00:09.679 --> 00:00:14.880
<v Speaker 1>there is this expectation of absolute mathematical precision, right.

4
00:00:15.000 --> 00:00:18.600
<v Speaker 2>Yeah. You calculate the exact load bearing weight of the steel.

5
00:00:18.559 --> 00:00:23.679
<v Speaker 1>Exactly, you pour the concrete bedrock to like very specific tolerances,

6
00:00:24.480 --> 00:00:28.640
<v Speaker 1>and you know mathematically what forces that structure can actually withstand.

7
00:00:28.760 --> 00:00:31.719
<v Speaker 2>Yeah, because the alternative is well catastrophic. I mean, it's

8
00:00:31.719 --> 00:00:36.000
<v Speaker 2>an industry completely built on rigorous, non negotiable laws of physics.

9
00:00:36.159 --> 00:00:39.479
<v Speaker 1>But then you look at modern web development. Yeah, and

10
00:00:39.520 --> 00:00:41.719
<v Speaker 1>if we're being completely honest here, for those of you

11
00:00:41.799 --> 00:00:44.359
<v Speaker 1>out there writing code every single day, a lot of

12
00:00:44.359 --> 00:00:46.880
<v Speaker 1>the time, it feels like we are, you know, building

13
00:00:46.920 --> 00:00:49.000
<v Speaker 1>skyscrapers out a wet cardboard and duct tape.

14
00:00:49.000 --> 00:00:51.640
<v Speaker 2>Oh for sure, just kind of crossing her finger, yeah.

15
00:00:51.479 --> 00:00:54.039
<v Speaker 1>Just hoping a strong wind doesn't knock the whole thing down. Yeah.

16
00:00:54.079 --> 00:00:57.719
<v Speaker 1>I mean, we patch vulnerabilities only after they get exploited, right,

17
00:00:57.840 --> 00:01:01.159
<v Speaker 1>We write endless tests just hoping to catch our own typos,

18
00:01:01.479 --> 00:01:03.679
<v Speaker 1>and we just sort of accept a certain level of

19
00:01:03.759 --> 00:01:07.000
<v Speaker 1>chaos as like the cost of doing business on the internet.

20
00:01:07.120 --> 00:01:10.480
<v Speaker 2>It's true, I mean we've really grown accustomed to run

21
00:01:10.519 --> 00:01:15.359
<v Speaker 2>time errors and broken states as this natural, unavoidable part

22
00:01:15.400 --> 00:01:17.760
<v Speaker 2>of the digital ecosystem, which is kind of wild when

23
00:01:17.760 --> 00:01:18.640
<v Speaker 2>you think about it.

24
00:01:18.439 --> 00:01:21.959
<v Speaker 1>It really is. Well, today we're exploring a completely different paradigm.

25
00:01:22.200 --> 00:01:25.280
<v Speaker 1>We're doing a deep dive into Michael Snoyman's book developing

26
00:01:25.319 --> 00:01:28.959
<v Speaker 1>Web Apps with Haskell and YES'D from a Riiley Media,

27
00:01:29.000 --> 00:01:32.280
<v Speaker 1>a classic, oh totally and frankly with its stark white

28
00:01:32.280 --> 00:01:36.799
<v Speaker 1>cover featuring this massive, intricately detailed whinoceros beetle and all.

29
00:01:36.719 --> 00:01:38.760
<v Speaker 2>The barcodes and QR codes on the back.

30
00:01:38.920 --> 00:01:43.599
<v Speaker 1>Yes, the physical book itself just screams like serious, rigorous

31
00:01:43.640 --> 00:01:47.159
<v Speaker 1>technical manual. But our mission today isn't to get bogged

32
00:01:47.159 --> 00:01:49.239
<v Speaker 1>down in academic syntax, so don't worry about that.

33
00:01:49.200 --> 00:01:49.840
<v Speaker 2>Oh definitely not.

34
00:01:50.040 --> 00:01:53.159
<v Speaker 1>We are here to decode what Snyman calls safety driven

35
00:01:53.200 --> 00:01:56.040
<v Speaker 1>web development. We're looking at how pairing the famously strict

36
00:01:56.120 --> 00:01:59.719
<v Speaker 1>language of Askell with this web framework called YESOD creates

37
00:02:00.439 --> 00:02:05.239
<v Speaker 1>to building incredibly fast, modular, and like virtually bug proof

38
00:02:05.319 --> 00:02:06.040
<v Speaker 1>web application.

39
00:02:06.400 --> 00:02:08.960
<v Speaker 2>And that's the real appeal, you know, for anyone who

40
00:02:09.000 --> 00:02:12.240
<v Speaker 2>is just exhausted from chasing bugs. We want to understand

41
00:02:12.280 --> 00:02:16.199
<v Speaker 2>the mechanisms, like the actual why and the how behind

42
00:02:16.240 --> 00:02:19.240
<v Speaker 2>this architecture, because we live in an Internet that is

43
00:02:19.360 --> 00:02:24.240
<v Speaker 2>absolutely flooded with security vulnerabilities and fragile systems, and we

44
00:02:24.280 --> 00:02:27.479
<v Speaker 2>are looking at a framework here that's designed to structurally

45
00:02:27.520 --> 00:02:30.280
<v Speaker 2>prevent those things from even compiling in the first place.

46
00:02:30.360 --> 00:02:32.639
<v Speaker 1>So to understand how it actually achieves that, we have

47
00:02:32.680 --> 00:02:36.599
<v Speaker 1>to start at the perimeter of the application. Snoyman talks

48
00:02:36.599 --> 00:02:40.360
<v Speaker 1>about this fundamental hurdle that he calls the boundary issue.

49
00:02:40.439 --> 00:02:42.080
<v Speaker 2>Yeah, the boundary issue.

50
00:02:42.120 --> 00:02:46.560
<v Speaker 1>This is crucial because inside a Haskell application, everything is pristine.

51
00:02:47.360 --> 00:02:51.199
<v Speaker 1>Haskell has a notoriously strict type system, so like the

52
00:02:51.199 --> 00:02:53.520
<v Speaker 1>string of text is a string, and integers and integer,

53
00:02:53.759 --> 00:02:56.360
<v Speaker 1>and the compiler physically will not allow them to mix.

54
00:02:56.479 --> 00:02:58.000
<v Speaker 2>Right, It's a very controlled environment.

55
00:02:58.080 --> 00:03:00.960
<v Speaker 1>But the Internet itself, it doesn't care about Haskell's rules

56
00:03:00.960 --> 00:03:01.520
<v Speaker 1>at all, not.

57
00:03:01.479 --> 00:03:03.680
<v Speaker 2>Even a little bit. I mean, the Internet is essentially

58
00:03:03.719 --> 00:03:08.360
<v Speaker 2>this wild West of raw, untyped bites. Whenever a user

59
00:03:08.400 --> 00:03:10.800
<v Speaker 2>submits a form, or you fetch data from a third

60
00:03:10.879 --> 00:03:13.960
<v Speaker 2>party API, or even just load a record from a database,

61
00:03:14.159 --> 00:03:16.960
<v Speaker 2>it enters your application as raw text.

62
00:03:16.840 --> 00:03:18.639
<v Speaker 1>Just a string of characters exactly.

63
00:03:18.719 --> 00:03:21.840
<v Speaker 2>So if a user type say twelve into an age field.

64
00:03:22.199 --> 00:03:24.759
<v Speaker 2>The web just sends the character one and the character two.

65
00:03:25.159 --> 00:03:29.960
<v Speaker 2>It's inherently untyped. So, however mathematically pure your application is

66
00:03:30.000 --> 00:03:33.919
<v Speaker 2>on the inside, every single boundary with the outside world

67
00:03:34.000 --> 00:03:37.520
<v Speaker 2>has to be meticulously sanitized. You have to translate the

68
00:03:37.639 --> 00:03:40.680
<v Speaker 2>chaots of the Internet into the strict order of Haskell.

69
00:03:41.159 --> 00:03:43.879
<v Speaker 1>Okay, let's unpack this. If you're building a typical node

70
00:03:43.960 --> 00:03:46.919
<v Speaker 1>or Python backen treating that boundary is like having a

71
00:03:47.000 --> 00:03:49.800
<v Speaker 1>nightclub bouncer who just asks, hey, are you twenty one

72
00:03:50.520 --> 00:03:52.120
<v Speaker 1>and takes a total stranger's word for it.

73
00:03:52.199 --> 00:03:53.240
<v Speaker 2>Yeah, that happens a lot.

74
00:03:53.360 --> 00:03:56.639
<v Speaker 1>It implicitly trusts the data. But yes, I treats the

75
00:03:56.639 --> 00:03:59.879
<v Speaker 1>web boundary like a bouncer who explicitly scans the ID like,

76
00:04:00.599 --> 00:04:04.080
<v Speaker 1>checks the data types, checks the hologram, and cross references

77
00:04:04.159 --> 00:04:04.680
<v Speaker 1>the database.

78
00:04:04.800 --> 00:04:05.919
<v Speaker 2>Right, they aren't messing around.

79
00:04:06.080 --> 00:04:08.759
<v Speaker 1>No, It enforces the data types at the door before

80
00:04:08.759 --> 00:04:10.159
<v Speaker 1>anyone is allowed inside the club.

81
00:04:10.280 --> 00:04:13.439
<v Speaker 2>That is a highly accurate analogy. And you know, this

82
00:04:13.520 --> 00:04:16.800
<v Speaker 2>strict boundary validation is actually where the framework gets its name.

83
00:04:17.439 --> 00:04:20.560
<v Speaker 2>The word yesod means foundation in Hebrew.

84
00:04:20.759 --> 00:04:21.959
<v Speaker 1>Oh wow. Yeah.

85
00:04:22.360 --> 00:04:25.680
<v Speaker 2>By explicitly declaring the exact data types you expect at

86
00:04:25.680 --> 00:04:28.879
<v Speaker 2>the boundary. You eliminate entire classes of bugs before the

87
00:04:28.879 --> 00:04:30.639
<v Speaker 2>code even executes.

88
00:04:30.399 --> 00:04:33.800
<v Speaker 1>Because if the incoming data doesn't perfectly match the expected type,

89
00:04:34.240 --> 00:04:36.079
<v Speaker 1>the foundation rejects it automatically.

90
00:04:36.160 --> 00:04:38.959
<v Speaker 2>Right, Exactly, You don't have to write fifty unit tests

91
00:04:38.959 --> 00:04:42.639
<v Speaker 2>to see what happens when a user submits malicious JavaScript

92
00:04:42.720 --> 00:04:45.000
<v Speaker 2>instead of their age, because the bouncer just handles it

93
00:04:45.040 --> 00:04:45.519
<v Speaker 2>at the door.

94
00:04:45.639 --> 00:04:48.079
<v Speaker 1>And what's interesting is that this foundation isn't just a

95
00:04:48.160 --> 00:04:52.560
<v Speaker 1>conceptual metaphor. I mean, every YASOD application literally revolves around

96
00:04:52.560 --> 00:04:56.600
<v Speaker 1>a specific foundation data type that you define yourself.

97
00:04:56.680 --> 00:04:59.000
<v Speaker 2>Right, you might just call it my app or whatever

98
00:04:59.040 --> 00:04:59.439
<v Speaker 2>you want.

99
00:04:59.519 --> 00:05:02.319
<v Speaker 1>Yeah, but it holds all the crucial initialized data for

100
00:05:02.360 --> 00:05:03.600
<v Speaker 1>your entire application.

101
00:05:03.759 --> 00:05:06.639
<v Speaker 2>It acts as the central nervous system when your application launches.

102
00:05:06.680 --> 00:05:09.879
<v Speaker 2>This foundation data type is instantiated and it holds your

103
00:05:09.959 --> 00:05:14.519
<v Speaker 2>database connection pools, your configuration files, your HTTP connection managers

104
00:05:14.560 --> 00:05:14.920
<v Speaker 2>all of it.

105
00:05:15.199 --> 00:05:16.879
<v Speaker 1>So it's all centralized exactly.

106
00:05:17.079 --> 00:05:19.199
<v Speaker 2>By tying everything your app needs to run to the

107
00:05:19.240 --> 00:05:22.759
<v Speaker 2>central foundation, which implements the YASAD type class, you ensure

108
00:05:22.800 --> 00:05:26.120
<v Speaker 2>that every single request has safe, concurrent access to the

109
00:05:26.199 --> 00:05:28.040
<v Speaker 2>exact same reliable state.

110
00:05:28.279 --> 00:05:30.319
<v Speaker 1>Okay, so we have this uldistrict bounder at the door

111
00:05:30.600 --> 00:05:33.199
<v Speaker 1>and a rock solid foundation inside. But you know, if

112
00:05:33.199 --> 00:05:35.199
<v Speaker 1>you're a developer listen to this, you're probably spotting the

113
00:05:35.199 --> 00:05:36.199
<v Speaker 1>obvious trade off here.

114
00:05:36.240 --> 00:05:38.399
<v Speaker 2>Oh yeah, the verbosity issue, right.

115
00:05:38.480 --> 00:05:41.759
<v Speaker 1>Because if I have to manually declare every single data type,

116
00:05:42.000 --> 00:05:45.120
<v Speaker 1>write a parser for every incoming string, and handle every

117
00:05:45.160 --> 00:05:48.199
<v Speaker 1>boundary explicitly, I mean I'm going to be writing thousands

118
00:05:48.279 --> 00:05:51.319
<v Speaker 1>of lines of tedious, repetitive boilerplate code.

119
00:05:51.759 --> 00:05:55.040
<v Speaker 2>Yes, that is the standard critique of strictly typed languages.

120
00:05:55.120 --> 00:05:59.160
<v Speaker 2>You usually trade brevity for safety. But ysad bypasses this

121
00:05:59.279 --> 00:06:04.079
<v Speaker 2>verbosity by leaning heavily into metaprogramming. Specifically, it uses a

122
00:06:04.079 --> 00:06:07.879
<v Speaker 2>feature of the language called template Haskell, alongside a related

123
00:06:07.920 --> 00:06:10.399
<v Speaker 2>tool called quasi quotes metaprogramming.

124
00:06:10.720 --> 00:06:13.680
<v Speaker 1>So basically, code that writes code precisely.

125
00:06:13.920 --> 00:06:17.240
<v Speaker 2>Template Haskell allows developers to write Haskell code that executes

126
00:06:17.360 --> 00:06:18.839
<v Speaker 2>during the compilation process.

127
00:06:19.399 --> 00:06:24.439
<v Speaker 1>During Yeah, during this code generates a Haskell abstract syntax

128
00:06:24.480 --> 00:06:28.680
<v Speaker 1>tree or AST, which is then fed back into the compiler.

129
00:06:28.720 --> 00:06:30.839
<v Speaker 2>Okay, let's slow down on that per second. An abstract

130
00:06:30.920 --> 00:06:33.800
<v Speaker 2>syntax tree. For those who maybe haven't taken a compiler

131
00:06:33.879 --> 00:06:36.360
<v Speaker 2>design course, what are we actually generating here.

132
00:06:37.839 --> 00:06:41.120
<v Speaker 1>Think of an ast like the grammatical diagram of a sentence,

133
00:06:41.399 --> 00:06:44.160
<v Speaker 1>but for code. When you write a line of code,

134
00:06:44.360 --> 00:06:46.279
<v Speaker 1>the compiler has to break it down into a tree

135
00:06:46.319 --> 00:06:48.439
<v Speaker 1>structure to understand the logic.

136
00:06:48.319 --> 00:06:51.160
<v Speaker 2>Like this is a noun, this is a verb, exactly, but.

137
00:06:51.279 --> 00:06:53.560
<v Speaker 1>In this case, this is a function, this is a variable,

138
00:06:53.600 --> 00:06:57.199
<v Speaker 1>this is an operator. With template Haskell, instead of typing

139
00:06:57.199 --> 00:07:00.360
<v Speaker 1>out repetitive text, you are giving the compiler a tiny

140
00:07:00.439 --> 00:07:04.000
<v Speaker 1>script that programmatically generates that structural tree for you.

141
00:07:04.160 --> 00:07:05.800
<v Speaker 2>Right, so, you might write a single line like a

142
00:07:05.839 --> 00:07:08.959
<v Speaker 2>dollar sign, followed by a function say hamlet hamsot file

143
00:07:09.040 --> 00:07:11.480
<v Speaker 2>myfile dot hamlet for an external file.

144
00:07:11.360 --> 00:07:14.360
<v Speaker 1>Or use quasi quotes right yeah, which let you embed

145
00:07:14.519 --> 00:07:18.519
<v Speaker 1>domain specific languages right inside your Haskell file using square

146
00:07:18.560 --> 00:07:23.959
<v Speaker 1>brackets and pipes like weimleth Hello World, and behind the scenes,

147
00:07:24.040 --> 00:07:27.600
<v Speaker 1>using a function called mech oshassade, the compiler translates that

148
00:07:27.680 --> 00:07:31.079
<v Speaker 1>one line into all the complex parsing and routing boilerplate

149
00:07:31.120 --> 00:07:32.560
<v Speaker 1>you normally have to type by hand.

150
00:07:32.720 --> 00:07:36.160
<v Speaker 2>It perfectly maps the untyped web requests to your strict

151
00:07:36.160 --> 00:07:37.279
<v Speaker 2>foundation data types.

152
00:07:37.360 --> 00:07:40.600
<v Speaker 1>But wait, if I'm letting the framework secretly generate all

153
00:07:40.600 --> 00:07:43.920
<v Speaker 1>my routing and parsing code behind the scenes. Don't I

154
00:07:44.000 --> 00:07:48.199
<v Speaker 1>lose control. I mean, in my experience, magic in programming

155
00:07:48.279 --> 00:07:49.800
<v Speaker 1>is great until it breaks, and then you have a

156
00:07:49.800 --> 00:07:51.519
<v Speaker 1>black box you literally can't debug.

157
00:07:51.720 --> 00:07:54.920
<v Speaker 2>What's fascinating here is that YESOD specifically avoids the black

158
00:07:54.959 --> 00:07:57.920
<v Speaker 2>box problem. Really how it provides a flag you can

159
00:07:57.959 --> 00:08:01.399
<v Speaker 2>pass to the compiler called dud dump splice ooh okay, yeah,

160
00:08:01.680 --> 00:08:04.079
<v Speaker 2>if you enable this, the compiler prints out exactly the

161
00:08:04.079 --> 00:08:05.879
<v Speaker 2>code it generated on your behalf.

162
00:08:05.720 --> 00:08:07.639
<v Speaker 1>No way, so you can see everything everything.

163
00:08:07.800 --> 00:08:09.600
<v Speaker 2>You can peek right under the hood and read the

164
00:08:09.720 --> 00:08:13.480
<v Speaker 2>routing data types. The parser functions the dispatch logic. It

165
00:08:13.519 --> 00:08:17.680
<v Speaker 2>handles the parsing, dispatching, and rendering perfectly in sync, saving

166
00:08:17.759 --> 00:08:21.759
<v Speaker 2>human fingers from inevitable typeos. But it keeps everything entirely

167
00:08:21.800 --> 00:08:23.439
<v Speaker 2>transparent to the developer.

168
00:08:23.120 --> 00:08:25.879
<v Speaker 1>So it's less like magic and more like having a

169
00:08:25.959 --> 00:08:30.079
<v Speaker 1>tireless junior developer who just writes perfect boilerplate at the

170
00:08:30.079 --> 00:08:32.600
<v Speaker 1>speed of light and always shows their work.

171
00:08:32.639 --> 00:08:33.480
<v Speaker 2>That's a great way to put it.

172
00:08:33.559 --> 00:08:35.559
<v Speaker 1>Yeah, and we could actually see the power of this

173
00:08:35.639 --> 00:08:39.840
<v Speaker 1>metaprogramming when we look at how YSAD handles routing, Because

174
00:08:39.919 --> 00:08:43.080
<v Speaker 1>this leads us to type safe URLs, which is huge.

175
00:08:43.159 --> 00:08:46.440
<v Speaker 2>This is arguably one of yusod's most defining features.

176
00:08:46.759 --> 00:08:47.039
<v Speaker 1>Yeah.

177
00:08:47.080 --> 00:08:49.320
<v Speaker 2>To appreciate it, we have to look at the routing pattern.

178
00:08:49.720 --> 00:08:52.879
<v Speaker 2>Unlike legacy systems that map a URL directly to a

179
00:08:52.919 --> 00:08:56.919
<v Speaker 2>physical file on a server like old PHP sites, YESOD

180
00:08:57.039 --> 00:08:58.759
<v Speaker 2>uses a front controller pattern.

181
00:08:58.600 --> 00:09:02.519
<v Speaker 1>Meaning every single request enters through one single point, and

182
00:09:02.600 --> 00:09:05.480
<v Speaker 1>YESAD acts as a traffic cop basically routing it to

183
00:09:05.480 --> 00:09:07.039
<v Speaker 1>the appropriate handler exactly.

184
00:09:07.279 --> 00:09:11.200
<v Speaker 2>But here is the critical difference. Instead of routing based

185
00:09:11.240 --> 00:09:15.000
<v Speaker 2>on raw strings of text, which are notoriously fragile, YESAD

186
00:09:15.080 --> 00:09:17.320
<v Speaker 2>routes are defined as data constructors.

187
00:09:17.399 --> 00:09:20.159
<v Speaker 1>Okay, let's define that, because data constructor is very specific

188
00:09:20.200 --> 00:09:23.919
<v Speaker 1>to functional programming. In a traditional framework, you tell a

189
00:09:23.960 --> 00:09:28.279
<v Speaker 1>system if the URL string is slash profile, slash home,

190
00:09:28.879 --> 00:09:33.200
<v Speaker 1>run this function. But a data constructor is a native type, right,

191
00:09:33.279 --> 00:09:34.840
<v Speaker 1>it's not text correct.

192
00:09:35.080 --> 00:09:37.720
<v Speaker 2>The convention in YESOD is to add a capital R

193
00:09:37.799 --> 00:09:40.559
<v Speaker 2>to the end for resource, so it becomes Homer Homer God.

194
00:09:40.639 --> 00:09:43.440
<v Speaker 2>Because Homer is a data constructor, it is a plain

195
00:09:43.559 --> 00:09:46.240
<v Speaker 2>old Haskell value. It's a structural type, just like a

196
00:09:46.279 --> 00:09:50.000
<v Speaker 2>boolean or an integer. So the compiler inherently understands what

197
00:09:50.039 --> 00:09:50.679
<v Speaker 2>Homer is.

198
00:09:50.919 --> 00:09:53.279
<v Speaker 1>Here's where it gets really interesting for anyone who has

199
00:09:53.279 --> 00:09:56.799
<v Speaker 1>ever had to refactor a massive codebase. If you define

200
00:09:56.840 --> 00:09:59.759
<v Speaker 1>your routes as data types, you don't use string. You

201
00:09:59.799 --> 00:10:01.360
<v Speaker 1>are ls in your HML anymore.

202
00:10:01.440 --> 00:10:02.639
<v Speaker 2>Nope, you use the data type.

203
00:10:02.840 --> 00:10:06.200
<v Speaker 1>Yeah. It's like using a dynamic GPS instead of drawing

204
00:10:06.200 --> 00:10:09.360
<v Speaker 1>a static line on a paper map. If a destination moves,

205
00:10:09.360 --> 00:10:11.919
<v Speaker 1>say you change a blog route from a numeric ID

206
00:10:12.120 --> 00:10:16.200
<v Speaker 1>to like a date based SLUG, the GPS updates your

207
00:10:16.279 --> 00:10:18.639
<v Speaker 1>route automatically. You don't have to go find and erase

208
00:10:18.679 --> 00:10:19.159
<v Speaker 1>the line on.

209
00:10:19.120 --> 00:10:21.799
<v Speaker 2>The paper map, and the maintenance implications of that are

210
00:10:21.879 --> 00:10:25.919
<v Speaker 2>just huge. Think about a standard web application. If you

211
00:10:26.480 --> 00:10:29.240
<v Speaker 2>change a route structure and forget to update a link

212
00:10:29.360 --> 00:10:32.200
<v Speaker 2>somewhere on page forty seven of your site, you wouldn't

213
00:10:32.200 --> 00:10:34.440
<v Speaker 2>know you made a mistake until the code is deployed

214
00:10:34.759 --> 00:10:37.519
<v Speaker 2>and a user actually complains about a four h four error.

215
00:10:37.639 --> 00:10:38.720
<v Speaker 1>Right, it's a nightmare.

216
00:10:38.879 --> 00:10:43.519
<v Speaker 2>But in YASAUD, the Haskell compiler physically refuses to compile

217
00:10:43.559 --> 00:10:46.480
<v Speaker 2>the application. It will throw an error and pinpoint every

218
00:10:46.519 --> 00:10:49.279
<v Speaker 2>single line in your entire code base that's still referencing

219
00:10:49.320 --> 00:10:50.679
<v Speaker 2>the old broken.

220
00:10:50.399 --> 00:10:53.159
<v Speaker 1>Route, So it effectively kills dead links at compile time,

221
00:10:53.399 --> 00:10:55.600
<v Speaker 1>they literally can't exist in production it does.

222
00:10:55.679 --> 00:10:57.519
<v Speaker 2>It's the death of the four h four error and

223
00:10:57.559 --> 00:11:01.039
<v Speaker 2>that metaprogramming we discussed earlier that rates a class called

224
00:11:01.080 --> 00:11:03.799
<v Speaker 2>render root to handle the translation back to text.

225
00:11:03.960 --> 00:11:06.360
<v Speaker 1>Right, because the browser still needs text eventually.

226
00:11:06.039 --> 00:11:08.919
<v Speaker 2>Yeah, exactly when it compiles your type safe links into

227
00:11:08.960 --> 00:11:13.360
<v Speaker 2>texts for the browser to read, render root generates absolute URLs,

228
00:11:13.600 --> 00:11:15.919
<v Speaker 2>meaning it includes the full domain name.

229
00:11:16.080 --> 00:11:16.879
<v Speaker 1>Oh interesting.

230
00:11:17.080 --> 00:11:19.480
<v Speaker 2>Yeah, this is a subtle but vital feature because it

231
00:11:19.519 --> 00:11:22.600
<v Speaker 2>consolidates your domain name to prevent search engines from penalizing

232
00:11:22.639 --> 00:11:26.919
<v Speaker 2>you for duplicate content across subdomains, and it ensures formats

233
00:11:26.919 --> 00:11:30.679
<v Speaker 2>that require absolute paths, like RSS or atom feeds, they

234
00:11:30.720 --> 00:11:32.759
<v Speaker 2>just function flawlessly out of the box.

235
00:11:33.039 --> 00:11:36.159
<v Speaker 1>Okay, so our inputs are meticulously sanitized by the foundation,

236
00:11:36.600 --> 00:11:40.159
<v Speaker 1>our boilerplate is generated perfectly via the AST, and our

237
00:11:40.240 --> 00:11:43.799
<v Speaker 1>routes are mathematically guaranteed to exist. Right. But eventually we

238
00:11:43.879 --> 00:11:46.679
<v Speaker 1>have to actually draw the page. We have to serve HTML,

239
00:11:46.960 --> 00:11:51.159
<v Speaker 1>CSS and JavaScript, and this requires a completely different approach

240
00:11:51.200 --> 00:11:52.200
<v Speaker 1>to templating, doesn't it.

241
00:11:52.360 --> 00:11:55.080
<v Speaker 2>Yes, To maintain that strict type safety all the way

242
00:11:55.120 --> 00:11:57.879
<v Speaker 2>down to the browser, ysaud uses a suite of templating

243
00:11:57.919 --> 00:12:01.679
<v Speaker 2>languages collectively named after Shakespeare. Love it's very clever. We

244
00:12:01.720 --> 00:12:04.759
<v Speaker 2>have Hamlet for HTML, Lucius and Cashus for CSS, and

245
00:12:04.840 --> 00:12:06.000
<v Speaker 2>Julius for JavaScript.

246
00:12:06.200 --> 00:12:09.720
<v Speaker 1>The naming convention is brilliant, and just like Haskell, these

247
00:12:09.799 --> 00:12:13.919
<v Speaker 1>languages have their own strict structural rules. Hamlet, for instance,

248
00:12:14.039 --> 00:12:17.879
<v Speaker 1>is white space sensitive. It relies on indentation instead of

249
00:12:17.879 --> 00:12:20.639
<v Speaker 1>closing tags. Right, so you don't write an opening tag,

250
00:12:20.759 --> 00:12:22.960
<v Speaker 1>type your text and then pray you remember the closing

251
00:12:22.960 --> 00:12:25.879
<v Speaker 1>tag later on. You just write the tag, indend, write

252
00:12:25.879 --> 00:12:28.799
<v Speaker 1>your text, and the structure is heavily implied.

253
00:12:28.480 --> 00:12:33.919
<v Speaker 2>Which naturally forces developers to write clean, visually hierarchical code.

254
00:12:33.960 --> 00:12:36.799
<v Speaker 2>You can't be sloppy with it. But the real ingenuity

255
00:12:36.879 --> 00:12:40.320
<v Speaker 2>of the Shakespearean templates is how they handle data interpolation

256
00:12:40.559 --> 00:12:41.279
<v Speaker 2>and security.

257
00:12:41.440 --> 00:12:42.519
<v Speaker 1>Yeah, let's talk about that.

258
00:12:42.799 --> 00:12:45.159
<v Speaker 2>When you inject a variable into Hamlet, you use a

259
00:12:45.200 --> 00:12:49.879
<v Speaker 2>specific syntax hash followed by braces like hashtag variable. And

260
00:12:49.919 --> 00:12:52.559
<v Speaker 2>to inject one of those types safe URLs we're talking about,

261
00:12:52.600 --> 00:12:54.720
<v Speaker 2>you use an at sign like at homer And.

262
00:12:54.679 --> 00:12:57.639
<v Speaker 1>Because the compiler knows the exact data type you're injecting,

263
00:12:58.039 --> 00:13:00.480
<v Speaker 1>it knows how to handle it safely. One of the

264
00:13:00.480 --> 00:13:05.120
<v Speaker 1>most terrifying vulnerabilities in web development cross site scripting or EXSS.

265
00:13:05.240 --> 00:13:07.480
<v Speaker 2>Yes, EXSS is a nightmare.

266
00:13:07.159 --> 00:13:09.480
<v Speaker 1>If you aren't familiar. This is what a malicious user

267
00:13:09.600 --> 00:13:12.960
<v Speaker 1>inputs a script into a text field like the blog comment,

268
00:13:13.240 --> 00:13:16.559
<v Speaker 1>and if your site renders that text blindly, it executes

269
00:13:16.600 --> 00:13:18.840
<v Speaker 1>their malicious script on your other user's machines.

270
00:13:19.039 --> 00:13:21.559
<v Speaker 2>It's a massive vector for data theft. I mean, it's

271
00:13:21.639 --> 00:13:25.279
<v Speaker 2>how session tokens get stolen. Most frameworks try to solve

272
00:13:25.320 --> 00:13:28.120
<v Speaker 2>this by running text through a filter to strip out

273
00:13:28.200 --> 00:13:29.639
<v Speaker 2>dangerous tags.

274
00:13:29.360 --> 00:13:31.759
<v Speaker 1>Like trying to sanitize it after the fact exactly.

275
00:13:31.960 --> 00:13:36.360
<v Speaker 2>But Hamlet prevents EXSS structurally. When you interpolate a standard

276
00:13:36.399 --> 00:13:40.360
<v Speaker 2>string variable into a Hamlet template, it automatically entity escapes

277
00:13:40.399 --> 00:13:41.480
<v Speaker 2>the string at the type level.

278
00:13:41.519 --> 00:13:42.720
<v Speaker 1>Okay, meaning what exactly?

279
00:13:42.840 --> 00:13:46.799
<v Speaker 2>It transforms characters like HTML brackets into harmless display entities,

280
00:13:47.080 --> 00:13:50.000
<v Speaker 2>so the script cannot execute because the browser is forced

281
00:13:50.000 --> 00:13:53.320
<v Speaker 2>to read it as literal text, not executable code.

282
00:13:53.480 --> 00:13:56.879
<v Speaker 1>But hold on, what if I want to render preexisting HTML.

283
00:13:57.279 --> 00:13:59.840
<v Speaker 1>Say have a developer blog and I want to display

284
00:14:00.039 --> 00:14:04.039
<v Speaker 1>colorized code snippets that already have like SPAN tags injected

285
00:14:04.080 --> 00:14:04.440
<v Speaker 1>into them.

286
00:14:04.559 --> 00:14:05.879
<v Speaker 2>Right, A very common use case.

287
00:14:06.120 --> 00:14:10.080
<v Speaker 1>Yeah, so if Hamlet escapes absolutely everything by default wanted,

288
00:14:10.200 --> 00:14:13.080
<v Speaker 1>just mangle my snippets and print the literal words, span

289
00:14:13.279 --> 00:14:15.159
<v Speaker 1>class equals across the screen.

290
00:14:15.320 --> 00:14:17.360
<v Speaker 2>If we connect this to the bigger picture, this is

291
00:14:17.399 --> 00:14:21.759
<v Speaker 2>where type level trust really outshines simple filtering. You saw.

292
00:14:21.799 --> 00:14:24.519
<v Speaker 2>It doesn't treat everything as a dumb string. It utilizes

293
00:14:24.559 --> 00:14:27.799
<v Speaker 2>an HTML data type, which is provided by a highly

294
00:14:27.840 --> 00:14:31.679
<v Speaker 2>optimized package called Blaze HTML. Okay, if you want to

295
00:14:31.720 --> 00:14:35.080
<v Speaker 2>render pre existing HTML, you don't just ask Hamlet to

296
00:14:35.120 --> 00:14:38.120
<v Speaker 2>ignore it. You run the data through a specific function

297
00:14:38.279 --> 00:14:40.000
<v Speaker 2>called pre escape to markup.

298
00:14:40.279 --> 00:14:43.519
<v Speaker 1>Uh. So you are explicitly coercing the type. You are

299
00:14:43.519 --> 00:14:46.240
<v Speaker 1>tagging it as safe HTML.

300
00:14:46.360 --> 00:14:49.639
<v Speaker 2>Exactly, you are changing its type. When Hamlet encounters data

301
00:14:49.679 --> 00:14:52.399
<v Speaker 2>that has been typed as HTML rather than a standard string,

302
00:14:52.720 --> 00:14:56.000
<v Speaker 2>it recognizes that you have explicitly vouched for this data,

303
00:14:56.039 --> 00:14:57.759
<v Speaker 2>so it passes it through unmodified.

304
00:14:57.799 --> 00:15:00.000
<v Speaker 1>So it's not a filter, it's a type contract exactly.

305
00:15:00.200 --> 00:15:02.879
<v Speaker 2>You have a system where the default state is absolute safety,

306
00:15:03.080 --> 00:15:06.559
<v Speaker 2>but you retain deliberate fine grain control to overwrite it,

307
00:15:06.600 --> 00:15:09.240
<v Speaker 2>all backed by the compiler verifying your data types.

308
00:15:09.320 --> 00:15:13.080
<v Speaker 1>That is beautifully elegant, but it brings us to a

309
00:15:13.480 --> 00:15:16.679
<v Speaker 1>major structural headache for modern component based design.

310
00:15:16.879 --> 00:15:18.559
<v Speaker 2>The CSS in JavaScript routing.

311
00:15:18.679 --> 00:15:22.559
<v Speaker 1>Yes, we have our HTML or CSS and our JavaScript

312
00:15:22.759 --> 00:15:26.480
<v Speaker 1>safely generated by the Shakespeare languages. But HTML demands a

313
00:15:26.600 --> 00:15:31.039
<v Speaker 1>very rigid document structure. Like CSS belongs globally up in

314
00:15:31.080 --> 00:15:33.840
<v Speaker 1>the head tag. JavaScript usually belongs down to the bottom

315
00:15:33.840 --> 00:15:36.679
<v Speaker 1>of the body tag. If I'm building a modular piece

316
00:15:36.720 --> 00:15:40.120
<v Speaker 1>of a web page, say a dynamic navigation bar, how

317
00:15:40.120 --> 00:15:43.279
<v Speaker 1>do I keep it CSS and JS organized without breaking

318
00:15:43.320 --> 00:15:44.360
<v Speaker 1>the document structure?

319
00:15:44.679 --> 00:15:48.440
<v Speaker 2>True modularity is notoriously difficult on the web for exactly

320
00:15:48.480 --> 00:15:51.159
<v Speaker 2>this reason. You build a beautiful component, but to use it,

321
00:15:51.200 --> 00:15:53.320
<v Speaker 2>you have to manually ensure its styles go to the

322
00:15:53.360 --> 00:15:55.960
<v Speaker 2>head and its scripts go to the footer. It is

323
00:15:56.279 --> 00:16:00.440
<v Speaker 2>but disad solves the structural disconnect with something called widgets.

324
00:16:00.159 --> 00:16:02.120
<v Speaker 1>It's the ultimate glue for the modern web.

325
00:16:02.159 --> 00:16:05.360
<v Speaker 2>As they say, yeah, widgets fundamentally shift how you architect

326
00:16:05.360 --> 00:16:07.559
<v Speaker 2>a page. Instead of viewing a web page as a

327
00:16:07.600 --> 00:16:11.519
<v Speaker 2>single monolithic tree of HTML, widgets treat the page as

328
00:16:11.559 --> 00:16:15.279
<v Speaker 2>an assembly of distinct components. A widget is a discrete

329
00:16:15.279 --> 00:16:19.399
<v Speaker 2>bundle that holds its own title, its own CSS declarations,

330
00:16:19.720 --> 00:16:22.759
<v Speaker 2>its own external scripts, and its own body content.

331
00:16:23.120 --> 00:16:25.200
<v Speaker 1>So how do you actually construct one? I mean, the

332
00:16:25.240 --> 00:16:28.240
<v Speaker 1>documentation highlights a type class called two widget. So you

333
00:16:28.279 --> 00:16:31.759
<v Speaker 1>take your Hamlet, your Lucius, and your Julius templates and

334
00:16:31.840 --> 00:16:35.919
<v Speaker 1>you bundle them together using Haskell's monad do notation right,

335
00:16:36.279 --> 00:16:40.279
<v Speaker 1>which if you aren't a Haskell developer, is essentially a

336
00:16:40.320 --> 00:16:43.919
<v Speaker 1>way to strictly sequence operations step by step so the

337
00:16:43.960 --> 00:16:47.399
<v Speaker 1>compiler can safely package all these different side effects like

338
00:16:47.440 --> 00:16:50.840
<v Speaker 1>adding a style or adding a script into one cohesive

339
00:16:50.919 --> 00:16:51.759
<v Speaker 1>monetic widget.

340
00:16:51.840 --> 00:16:53.960
<v Speaker 2>And once you have that cohesive widget, you use a

341
00:16:54.000 --> 00:16:56.720
<v Speaker 2>function called default layout to actually render the page.

342
00:16:56.799 --> 00:16:59.240
<v Speaker 1>Of trying to picture how default layout works. Yeah, and

343
00:16:59.240 --> 00:17:01.320
<v Speaker 1>it's almost like a post sorting facility.

344
00:17:00.960 --> 00:17:02.200
<v Speaker 2>Right now, that's a good way to look at it.

345
00:17:02.279 --> 00:17:05.559
<v Speaker 1>You hand it this bundled package, and the sorting facility unwraps.

346
00:17:05.559 --> 00:17:08.039
<v Speaker 1>It takes the CSS and routes it directly to the

347
00:17:08.039 --> 00:17:10.759
<v Speaker 1>head container, takes the JavaScript and routes it to the

348
00:17:10.799 --> 00:17:14.119
<v Speaker 1>script compaigner, and takes the HTML and places it perfectly

349
00:17:14.119 --> 00:17:17.079
<v Speaker 1>in the body. It automatically sorts everything into its legally

350
00:17:17.079 --> 00:17:18.279
<v Speaker 1>correct place in the document.

351
00:17:18.400 --> 00:17:19.480
<v Speaker 2>That is exactly what happens.

352
00:17:19.480 --> 00:17:21.279
<v Speaker 1>It does the heavy lifting for you, But I have

353
00:17:21.319 --> 00:17:23.200
<v Speaker 1>to push back here for a second. If I'm reusing

354
00:17:23.240 --> 00:17:26.480
<v Speaker 1>these widgets, Let's say I dropped three different dynamic image

355
00:17:26.519 --> 00:17:29.799
<v Speaker 1>carousels onto the exact same page. Don't I run the

356
00:17:29.920 --> 00:17:33.480
<v Speaker 1>risk of CSS class name collisions? Oh? Sure, because if

357
00:17:33.559 --> 00:17:37.240
<v Speaker 1>the framework is auto sorting my CSS into the global headtag,

358
00:17:37.680 --> 00:17:40.279
<v Speaker 1>I feel like that's just a recipe for styling nightmares

359
00:17:40.279 --> 00:17:41.039
<v Speaker 1>and dombloat.

360
00:17:41.440 --> 00:17:44.279
<v Speaker 2>Well it would be if you were hard coding the

361
00:17:44.359 --> 00:17:45.079
<v Speaker 2>class names.

362
00:17:45.359 --> 00:17:45.559
<v Speaker 1>Ah.

363
00:17:45.599 --> 00:17:48.839
<v Speaker 2>Okay, Yes, it anticipates this with a function called new

364
00:17:48.880 --> 00:17:52.319
<v Speaker 2>ident new dent. Yeah. When you build a widget, you

365
00:17:52.359 --> 00:17:56.519
<v Speaker 2>can use new ident to automatically generate mathematically unique IDs

366
00:17:56.559 --> 00:18:00.000
<v Speaker 2>and class names for that specific instance of the widget.

367
00:18:00.119 --> 00:18:03.640
<v Speaker 2>Oh wow, it scopes the CSS locally. You can drop

368
00:18:03.640 --> 00:18:06.640
<v Speaker 2>that image carousel onto the page twenty times, and new

369
00:18:06.680 --> 00:18:09.680
<v Speaker 2>iden guarantees there will be zero styling collisions.

370
00:18:09.839 --> 00:18:13.240
<v Speaker 1>So what does this all mean? The modularity is basically absolute.

371
00:18:13.319 --> 00:18:15.759
<v Speaker 1>You write the complex logic once and you can drop

372
00:18:15.759 --> 00:18:18.279
<v Speaker 1>it anywhere, knowing it will sort its own dependencies and

373
00:18:18.319 --> 00:18:20.519
<v Speaker 1>never bleed into the rest of the page. And from

374
00:18:20.559 --> 00:18:23.200
<v Speaker 1>a developer experience standpoint, you really get the best of

375
00:18:23.240 --> 00:18:28.599
<v Speaker 1>both worlds. For local development, YASAD provides this tool yesad Devil,

376
00:18:28.799 --> 00:18:31.400
<v Speaker 1>which auto rebuilds your code on the fly, so you

377
00:18:31.440 --> 00:18:35.480
<v Speaker 1>get the rapid iterative prototyping speed of a dynamic scripting language.

378
00:18:35.559 --> 00:18:37.839
<v Speaker 2>It feels very fast to work with, but then when

379
00:18:37.839 --> 00:18:40.839
<v Speaker 2>you compile it for production, you deploy it on ysad's

380
00:18:40.960 --> 00:18:45.160
<v Speaker 2>custom web server called WARP, and because it's compiled down

381
00:18:45.200 --> 00:18:49.119
<v Speaker 2>to machine code, the memory footprint is incredibly small and

382
00:18:49.200 --> 00:18:54.079
<v Speaker 2>the raw performance is frankly staggering compared to traditional interpreted frameworks.

383
00:18:54.200 --> 00:18:56.559
<v Speaker 1>So to pull all of this together for everyone listening,

384
00:18:56.839 --> 00:18:59.400
<v Speaker 1>we looked at how Haskell's strict typing acts as a

385
00:18:59.440 --> 00:19:03.160
<v Speaker 1>boundary be right, how the foundation provides a safe central state,

386
00:19:03.519 --> 00:19:07.319
<v Speaker 1>how metaprogramming and type safe URLs just eradicate deadlinks, how

387
00:19:07.359 --> 00:19:12.079
<v Speaker 1>Shakespearean templates structurally defeat XSS, and how modular widgets cleanly

388
00:19:12.079 --> 00:19:13.400
<v Speaker 1>assemble the final product.

389
00:19:13.640 --> 00:19:17.799
<v Speaker 2>It really is a comprehensive architecture for building bulletproof web applications.

390
00:19:17.880 --> 00:19:20.319
<v Speaker 2>It redefines the baseline of what we should expect from

391
00:19:20.319 --> 00:19:20.759
<v Speaker 2>our tools.

392
00:19:20.839 --> 00:19:22.559
<v Speaker 1>Yeah, it does, And you know.

393
00:19:22.920 --> 00:19:25.079
<v Speaker 2>This raises an important question something for you to think

394
00:19:25.079 --> 00:19:25.960
<v Speaker 2>about after we sign off.

395
00:19:26.079 --> 00:19:26.599
<v Speaker 1>Cable's here.

396
00:19:27.359 --> 00:19:30.640
<v Speaker 2>If you saw it uses compile time metaprogramming to automatically

397
00:19:30.720 --> 00:19:34.759
<v Speaker 2>handle routing logic, enforce data sanitization at the boundaries, and

398
00:19:34.880 --> 00:19:39.680
<v Speaker 2>structurally prevent EXSS attacks before the serer even starts. Yeah, well,

399
00:19:39.799 --> 00:19:43.920
<v Speaker 2>could this paradigm eventually make manual unit testing obsolete for

400
00:19:44.119 --> 00:19:45.119
<v Speaker 2>UI and routing?

401
00:19:45.279 --> 00:19:45.759
<v Speaker 1>Oh wow?

402
00:19:46.200 --> 00:19:49.240
<v Speaker 2>I mean if the compiler mathematically guarantees the code is

403
00:19:49.279 --> 00:19:53.200
<v Speaker 2>structurally perfect, do we still need armies of QA testers

404
00:19:53.240 --> 00:19:57.279
<v Speaker 2>writing brittle browser automation scripts or does the compiler itself

405
00:19:57.319 --> 00:19:59.319
<v Speaker 2>evolve into the ultimate QA department.

406
00:19:59.640 --> 00:20:02.279
<v Speaker 1>That is a wild thought to leave on a world

407
00:20:02.319 --> 00:20:06.000
<v Speaker 1>where the compiler actually does the QA for you. Well,

408
00:20:06.000 --> 00:20:08.079
<v Speaker 1>that is all the time we have for today's deep dive.

409
00:20:08.200 --> 00:20:10.519
<v Speaker 1>Thank you for joining us as we explore the underlying

410
00:20:10.559 --> 00:20:14.400
<v Speaker 1>mechanisms of safety driven web development. Remember, the Internet might

411
00:20:14.440 --> 00:20:16.640
<v Speaker 1>be made of wet cardboard and duct tape, but your

412
00:20:16.680 --> 00:20:20.720
<v Speaker 1>applications foundation definitely doesn't have to be. Keep asking questions,

413
00:20:20.799 --> 00:20:23.880
<v Speaker 1>keep exploring, and keep digging deep. We'll catch you next time.
