1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
|
<!-- Automatically generated by emacsconf-publish-after-page -->
<a name="haskell-mainVideo-transcript"></a>
# Transcript
[[!template new="1" text="Today, I will talk about Haskell code exploration for Emacs." start="00:00:00.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="What is Haskell? It is a purely functional language." start="00:00:03.500" video="mainVideo-haskell" id="subtitle"]]
[[!template text="For example, every value in Haskell is immutable." start="00:00:06.500" video="mainVideo-haskell" id="subtitle"]]
[[!template text="And it is the main compiler of Haskell, GHC." start="00:00:09.500" video="mainVideo-haskell" id="subtitle"]]
[[!template text="It provides API for the whole compilation pipeline." start="00:00:13.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="For example, the tools mentioned in this talk," start="00:00:16.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="including hcel and haddorg," start="00:00:18.424" video="mainVideo-haskell" id="subtitle"]]
[[!template text="they use, they heavily utilize the GHC front-end API" start="00:00:20.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="for parsing and understanding" start="00:00:24.500" video="mainVideo-haskell" id="subtitle"]]
[[!template text="the identifiers in Haskell source files." start="00:00:26.744" video="mainVideo-haskell" id="subtitle"]]
[[!template text="Roughly speaking," start="00:00:29.500" video="mainVideo-haskell" id="subtitle"]]
[[!template new="1" text="a Haskell program consists of several parts." start="00:00:31.544" video="mainVideo-haskell" id="subtitle"]]
[[!template text="it begins with some front matters, including," start="00:00:34.664" video="mainVideo-haskell" id="subtitle"]]
[[!template text="for example, language extensions," start="00:00:37.064" video="mainVideo-haskell" id="subtitle"]]
[[!template text="which are optional language features one might want to use" start="00:00:40.024" video="mainVideo-haskell" id="subtitle"]]
[[!template text="for convenience." start="00:00:44.064" video="mainVideo-haskell" id="subtitle"]]
[[!template text="The front matters also contain module exports." start="00:00:48.464" video="mainVideo-haskell" id="subtitle"]]
[[!template text="So for example, here we define," start="00:00:52.500" video="mainVideo-haskell" id="subtitle"]]
[[!template text="we declare module F2Md.Config" start="00:00:55.784" video="mainVideo-haskell" id="subtitle"]]
[[!template text="for this Haskell source file," start="00:00:58.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="which exports these four identifiers" start="00:01:00.984" video="mainVideo-haskell" id="subtitle"]]
[[!template text="that other source files can use when importing F2Md.Config." start="00:01:03.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="And the next will be" start="00:01:07.500" video="mainVideo-haskell" id="subtitle"]]
[[!template text="a block of imports so that we can use libraries" start="00:01:10.784" video="mainVideo-haskell" id="subtitle"]]
[[!template text="and identifiers in these libraries." start="00:01:14.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="The bulk of a Haskell source file normally is" start="00:01:17.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="a list of declarations," start="00:01:21.744" video="mainVideo-haskell" id="subtitle"]]
[[!template text="including values, types, and instances, and so on." start="00:01:23.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="The difference between a value and a type is that" start="00:01:26.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="the type of a value is a type," start="00:01:29.184" video="mainVideo-haskell" id="subtitle"]]
[[!template text="and the type of a type is a kind." start="00:01:30.500" video="mainVideo-haskell" id="subtitle"]]
[[!template new="1" text="For example, here's a small block of Haskell source code." start="00:01:34.064" video="mainVideo-haskell" id="subtitle"]]
[[!template text="We define Range type" start="00:01:38.584" video="mainVideo-haskell" id="subtitle"]]
[[!template text="from a lower-end integer to a higher-end integer." start="00:01:41.504" video="mainVideo-haskell" id="subtitle"]]
[[!template text="We also declare a value r of the type Range," start="00:01:45.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="which is Range from 2 to 7," start="00:01:51.464" video="mainVideo-haskell" id="subtitle"]]
[[!template text="because in Haskell, we like to--" start="00:01:54.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="by default, functions can be curried," start="00:02:01.104" video="mainVideo-haskell" id="subtitle"]]
[[!template text="which basically means, by default, we want to utilize" start="00:02:04.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="the partial application of functions." start="00:02:09.904" video="mainVideo-haskell" id="subtitle"]]
[[!template text="We don't require parens surrounding arguments" start="00:02:12.000" video="mainVideo-haskell" id="subtitle"]]
[[!template new="1" text="when invoking a function." start="00:02:17.384" video="mainVideo-haskell" id="subtitle"]]
[[!template text="That makes it possible, if you want," start="00:02:19.464" video="mainVideo-haskell" id="subtitle"]]
[[!template text="to write Haskell like Lisp" start="00:02:22.725" video="mainVideo-haskell" id="subtitle"]]
[[!template text="by adding a bit of redundant parens." start="00:02:25.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="So for example," start="00:02:28.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="here are two blocks of code, one Lisp, one Haskell," start="00:02:30.144" video="mainVideo-haskell" id="subtitle"]]
[[!template text="and they look quite similar to each other." start="00:02:33.784" video="mainVideo-haskell" id="subtitle"]]
[[!template text="What is a code explorer?" start="00:02:36.000" video="mainVideo-haskell" id="subtitle"]]
[[!template new="1" text="A code explorer is a tool" start="00:02:38.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="to browse its code base to its code comprehension." start="00:02:39.544" video="mainVideo-haskell" id="subtitle"]]
[[!template text="Code explorer commonly comes with" start="00:02:42.724" video="mainVideo-haskell" id="subtitle"]]
[[!template text="several functionalities or features," start="00:02:45.424" video="mainVideo-haskell" id="subtitle"]]
[[!template text="including a cross-referencer," start="00:02:47.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="which allows going to definitions of an identifier at points" start="00:02:49.344" video="mainVideo-haskell" id="subtitle"]]
[[!template text="or looking up references of an identifier," start="00:02:53.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="like where it is used." start="00:02:56.544" video="mainVideo-haskell" id="subtitle"]]
[[!template text="So the example in Emacs would be xref." start="00:02:58.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="Code explorer also would be able to show you" start="00:03:04.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="documentation and signatures of identifiers at points." start="00:03:07.704" video="mainVideo-haskell" id="subtitle"]]
[[!template text="In Emacs, that would be eldoc." start="00:03:10.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="It also commonly allows you to search for identifiers." start="00:03:13.984" video="mainVideo-haskell" id="subtitle"]]
[[!template text="Something like that in Emacs" start="00:03:17.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="could be describe-function and find-function." start="00:03:19.984" video="mainVideo-haskell" id="subtitle"]]
[[!template text="Code explorer is normally" start="00:03:22.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="quite often implemented in two parts," start="00:03:24.784" video="mainVideo-haskell" id="subtitle"]]
[[!template text="the indexer and the server," start="00:03:27.464" video="mainVideo-haskell" id="subtitle"]]
[[!template text="where the indexer parses the source code files," start="00:03:28.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="indexes the identifiers," start="00:03:32.584" video="mainVideo-haskell" id="subtitle"]]
[[!template text="and stores the information of identifiers" start="00:03:34.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="like the definition, size, and the currencies," start="00:03:36.384" video="mainVideo-haskell" id="subtitle"]]
[[!template text="either in databases or in files." start="00:03:38.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="The other part is the server," start="00:03:42.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="which uses the database created by the indexer" start="00:03:44.544" video="mainVideo-haskell" id="subtitle"]]
[[!template text="to serve the information of the identifier." start="00:03:49.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="Before I present my solution to code exploring," start="00:03:53.104" video="mainVideo-haskell" id="subtitle"]]
[[!template new="1" text="some description of prior art is in order." start="00:03:57.104" video="mainVideo-haskell" id="subtitle"]]
[[!template text="There are several tools that you can use" start="00:04:01.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="to aid code exploration," start="00:04:05.384" video="mainVideo-haskell" id="subtitle"]]
[[!template text="including tech-based tools like hasktags and hs-tags." start="00:04:08.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="The limitation with these tools" start="00:04:13.544" video="mainVideo-haskell" id="subtitle"]]
[[!template text="is they are focused on the current projects only" start="00:04:15.584" video="mainVideo-haskell" id="subtitle"]]
[[!template text="and do not work" start="00:04:18.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="for cross-packaging reference and definition." start="00:04:19.704" video="mainVideo-haskell" id="subtitle"]]
[[!template text="Another problem with the tag-based tools is" start="00:04:26.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="they might not handle symbols with the same name properly." start="00:04:31.045" video="mainVideo-haskell" id="subtitle"]]
[[!template text="Sometimes they get confused," start="00:04:34.784" video="mainVideo-haskell" id="subtitle"]]
[[!template text="and they ask you to choose which definition," start="00:04:36.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="what is the correct definition site," start="00:04:43.424" video="mainVideo-haskell" id="subtitle"]]
[[!template text="even though the occurrence of the symbol" start="00:04:46.024" video="mainVideo-haskell" id="subtitle"]]
[[!template text="or the symbol at point has only one definition ambiguously." start="00:04:49.344" video="mainVideo-haskell" id="subtitle"]]
[[!template text="Another tool is the haskell-mode." start="00:04:55.000" video="mainVideo-haskell" id="subtitle"]]
[[!template new="1" text="It has some limited support for eldoc" start="00:04:58.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="by displaying the signature of an identifier at points," start="00:05:02.784" video="mainVideo-haskell" id="subtitle"]]
[[!template text="but the identifier has to be something" start="00:05:06.704" video="mainVideo-haskell" id="subtitle"]]
[[!template text="that is commonly known or sort of built-in" start="00:05:11.864" video="mainVideo-haskell" id="subtitle"]]
[[!template text="or come from the base library of Haskell." start="00:05:15.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="So for example," start="00:05:18.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="it works for common functions like head and tail." start="00:05:20.344" video="mainVideo-haskell" id="subtitle"]]
[[!template text="And you can see that the signature is displayed here." start="00:05:24.344" video="mainVideo-haskell" id="subtitle"]]
[[!template text="However, it does not work for," start="00:05:27.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="let's say, IO. IO is a type." start="00:05:29.664" video="mainVideo-haskell" id="subtitle"]]
[[!template text="Maybe that's the reason." start="00:05:31.904" video="mainVideo-haskell" id="subtitle"]]
[[!template text="Let's find another function" start="00:05:33.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="that's not from the base library." start="00:05:37.424" video="mainVideo-haskell" id="subtitle"]]
[[!template text="toJSON is from the Aeson library," start="00:05:40.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="so no signature is displayed here." start="00:05:42.000" video="mainVideo-haskell" id="subtitle"]]
[[!template new="1" text="It also provides" start="00:05:47.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="some sort of goto-declaration functionality" start="00:05:51.264" video="mainVideo-haskell" id="subtitle"]]
[[!template text="to jump to any declaration in a file." start="00:05:53.424" video="mainVideo-haskell" id="subtitle"]]
[[!template text="To do that, one has to first run haskell-decl-scan-mode" start="00:05:56.424" video="mainVideo-haskell" id="subtitle"]]
[[!template text="to enter this minor mode." start="00:06:00.664" video="mainVideo-haskell" id="subtitle"]]
[[!template text="Then we can run imenu to go to any definition," start="00:06:03.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="to go to any declaration, like getHomeR." start="00:06:08.144" video="mainVideo-haskell" id="subtitle"]]
[[!template text="Apparently, after running that," start="00:06:11.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="we are able to go to definition." start="00:06:13.824" video="mainVideo-haskell" id="subtitle"]]
[[!template text="So for example, let's see," start="00:06:16.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="we want to find definition of getCityJR." start="00:06:19.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="And indeed, it works" start="00:06:22.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="if it's within the same source file, of course." start="00:06:25.624" video="mainVideo-haskell" id="subtitle"]]
[[!template text="It still does not work for cross-packaging identifiers." start="00:06:28.624" video="mainVideo-haskell" id="subtitle"]]
[[!template text="So HandlerFor is probably an identifier from servant." start="00:06:32.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="Or no, not necessarily servant. Maybe WAI." start="00:06:37.024" video="mainVideo-haskell" id="subtitle"]]
[[!template text="Anyway, it's another library." start="00:06:40.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="And how about find-references?" start="00:06:43.504" video="mainVideo-haskell" id="subtitle"]]
[[!template new="1" text="find-references also works somehow for this file." start="00:06:50.504" video="mainVideo-haskell" id="subtitle"]]
[[!template text="How about WidgetFor?" start="00:07:01.224" video="mainVideo-haskell" id="subtitle"]]
[[!template text="It works for WidgetFor too." start="00:07:06.784" video="mainVideo-haskell" id="subtitle"]]
[[!template text="It has some support for goto-definition and find-references." start="00:07:13.744" video="mainVideo-haskell" id="subtitle"]]
[[!template text="But as usual, it does not support such things cross-package." start="00:07:18.000" video="mainVideo-haskell" id="subtitle"]]
[[!template new="1" text="And finally, we have" start="00:07:26.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="the Sledgehammer HLS Haskell language server." start="00:07:27.365" video="mainVideo-haskell" id="subtitle"]]
[[!template text="It can be used with EGLOT." start="00:07:31.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="But the problem with HLS, HLS has many many features" start="00:07:33.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="because it is a language server," start="00:07:40.904" video="mainVideo-haskell" id="subtitle"]]
[[!template text="like renaming, like eldoc for standard libraries, and so on." start="00:07:42.944" video="mainVideo-haskell" id="subtitle"]]
[[!template text="But the problem with HLS is, one, that it is very, very slow." start="00:07:51.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="And I wouldn't use it with my laptop." start="00:07:57.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="And two, it also does not support cross-package referencing." start="00:08:00.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="In fact, there's an outstanding GitHub issue about this." start="00:08:05.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="So cross-package referencing and goto-definition" start="00:08:08.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="is sort of a common shortfall," start="00:08:13.064" video="mainVideo-haskell" id="subtitle"]]
[[!template text="a common problem for these existing Haskell code explorers." start="00:08:17.264" video="mainVideo-haskell" id="subtitle"]]
[[!template new="1" text="Then finally, we also have hoogle and hackage." start="00:08:21.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="Hoogle is a search engine for Haskell identifiers," start="00:08:23.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="and the results link to Hackage," start="00:08:28.384" video="mainVideo-haskell" id="subtitle"]]
[[!template text="which is the Haskell documentation website" start="00:08:30.744" video="mainVideo-haskell" id="subtitle"]]
[[!template text="for all Haskell libraries." start="00:08:33.704" video="mainVideo-haskell" id="subtitle"]]
[[!template text="Haskell Hackage has functionality" start="00:08:35.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="where you can jump to the source code file rendered in HTML," start="00:08:40.104" video="mainVideo-haskell" id="subtitle"]]
[[!template text="and you can click on the identifiers there" start="00:08:45.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="to jump to definitions," start="00:08:49.544" video="mainVideo-haskell" id="subtitle"]]
[[!template text="but it does not support find references," start="00:08:51.624" video="mainVideo-haskell" id="subtitle"]]
[[!template text="and it is rather basic." start="00:08:54.144" video="mainVideo-haskell" id="subtitle"]]
[[!template new="1" text="Then I learned about haskell-code-explorer," start="00:08:59.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="which is a fully-fledged Haskell code explorer." start="00:09:01.744" video="mainVideo-haskell" id="subtitle"]]
[[!template text="It is written by someone else." start="00:09:05.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="It is a web application" start="00:09:07.824" video="mainVideo-haskell" id="subtitle"]]
[[!template text="for exploring Haskell package codebases." start="00:09:09.264" video="mainVideo-haskell" id="subtitle"]]
[[!template text="The official reference instance for haskell-code-explorer" start="00:09:12.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="is available at this URL, which I will demo soon." start="00:09:16.344" video="mainVideo-haskell" id="subtitle"]]
[[!template text="What I did with these packages... I ported it to GHC 9.2." start="00:09:19.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="I renamed it to hcel because I want to focus on Emacs clients" start="00:09:25.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="rather than JavaScript clients, which I will explain later." start="00:09:29.144" video="mainVideo-haskell" id="subtitle"]]
[[!template text="And I also wrote an Emacs client package, of course." start="00:09:31.000" video="mainVideo-haskell" id="subtitle"]]
[[!template new="1" text="This is what haskell-code-explorer looks like." start="00:09:37.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="On the homepage, it is a list of indexed packages" start="00:09:41.504" video="mainVideo-haskell" id="subtitle"]]
[[!template text="indexed by the indexer." start="00:09:47.024" video="mainVideo-haskell" id="subtitle"]]
[[!template text="One can filter it by the package name" start="00:09:50.144" video="mainVideo-haskell" id="subtitle"]]
[[!template text="or look for identifiers directly across all packages." start="00:09:53.944" video="mainVideo-haskell" id="subtitle"]]
[[!template text="Let's have a look at base. There are three versions." start="00:10:05.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="Let's have a look at the latest version, 4.12.0.0." start="00:10:09.984" video="mainVideo-haskell" id="subtitle"]]
[[!template text="Once entering the package view," start="00:10:15.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="you are shown a list of all modules by their path," start="00:10:19.064" video="mainVideo-haskell" id="subtitle"]]
[[!template text="as well as a tree of these module files." start="00:10:24.544" video="mainVideo-haskell" id="subtitle"]]
[[!template text="You can filter by module name or file name," start="00:10:29.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="or you can search for identifier within the same package" start="00:10:32.624" video="mainVideo-haskell" id="subtitle"]]
[[!template text="or in all packages." start="00:10:34.424" video="mainVideo-haskell" id="subtitle"]]
[[!template text="Let's say we want to learn about Control.Monad." start="00:10:36.000" video="mainVideo-haskell" id="subtitle"]]
[[!template new="1" text="Now we are in the module view." start="00:10:43.304" video="mainVideo-haskell" id="subtitle"]]
[[!template text="The source file is presented to you," start="00:10:46.984" video="mainVideo-haskell" id="subtitle"]]
[[!template text="and it has links to identifiers." start="00:10:49.904" video="mainVideo-haskell" id="subtitle"]]
[[!template text="When you hover over them, the documentation shows up," start="00:10:55.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="including the signature where it is defined." start="00:11:01.904" video="mainVideo-haskell" id="subtitle"]]
[[!template text="You can go to its definition or find references." start="00:11:05.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="Let's say we want to go to the definition of Monad." start="00:11:10.344" video="mainVideo-haskell" id="subtitle"]]
[[!template text="It jumps to the definition site of the monad type class." start="00:11:20.264" video="mainVideo-haskell" id="subtitle"]]
[[!template text="If we click at the definition site," start="00:11:25.584" video="mainVideo-haskell" id="subtitle"]]
[[!template text="it brings up a list of references." start="00:11:28.104" video="mainVideo-haskell" id="subtitle"]]
[[!template text="On the left, you can choose" start="00:11:32.224" video="mainVideo-haskell" id="subtitle"]]
[[!template text="which package you want to find references of monad in." start="00:11:33.744" video="mainVideo-haskell" id="subtitle"]]
[[!template text="Let's look at the random one, avwx." start="00:11:39.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="Here is a list of results where Monad is used in avwx." start="00:11:47.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="This is a module path." start="00:11:54.144" video="mainVideo-haskell" id="subtitle"]]
[[!template text="One can go to any of these results." start="00:11:57.864" video="mainVideo-haskell" id="subtitle"]]
[[!template text="We can search for things in all packages" start="00:12:06.424" video="mainVideo-haskell" id="subtitle"]]
[[!template text="or in the current package." start="00:12:07.944" video="mainVideo-haskell" id="subtitle"]]
[[!template text="Let’s say I want to search for "Read"" start="00:12:09.584" video="mainVideo-haskell" id="subtitle"]]
[[!template text="I think this is the "Read" that is commonly used in Haskell," start="00:12:13.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="the read type class for parsing strings into values." start="00:12:19.344" video="mainVideo-haskell" id="subtitle"]]
[[!template text="I think that is more or less it." start="00:12:25.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="That is the Haskell Code Explorer web application" start="00:12:31.104" video="mainVideo-haskell" id="subtitle"]]
[[!template text="in all its glory." start="00:12:34.624" video="mainVideo-haskell" id="subtitle"]]
[[!template new="1" text="Let's go back to the slides." start="00:12:38.304" video="mainVideo-haskell" id="subtitle"]]
[[!template text="That was the web application," start="00:12:40.984" video="mainVideo-haskell" id="subtitle"]]
[[!template text="which is basically a JavaScript client" start="00:12:43.464" video="mainVideo-haskell" id="subtitle"]]
[[!template text="that talks to the server" start="00:12:46.544" video="mainVideo-haskell" id="subtitle"]]
[[!template text="by sending requests and receiving" start="00:12:48.744" video="mainVideo-haskell" id="subtitle"]]
[[!template text="and parsing the JSON results or JSON responses." start="00:12:51.064" video="mainVideo-haskell" id="subtitle"]]
[[!template text="Initially, I was interested in hacking the web client." start="00:12:55.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="It uses the ember.js web framework." start="00:13:02.504" video="mainVideo-haskell" id="subtitle"]]
[[!template text="The first thing to do was to npm install ember-cli." start="00:13:05.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="It gives me 12 vulnerabilities," start="00:13:09.944" video="mainVideo-haskell" id="subtitle"]]
[[!template text="4 low, 2 moderate, 3 high, 3 critical." start="00:13:16.224" video="mainVideo-haskell" id="subtitle"]]
[[!template text="I don't know how often it is the case" start="00:13:19.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="when we don't really care about these nasty vulnerabilities" start="00:13:26.184" video="mainVideo-haskell" id="subtitle"]]
[[!template text="from Node.js or npm because they are so common." start="00:13:33.064" video="mainVideo-haskell" id="subtitle"]]
[[!template text="I don't quite like that." start="00:13:36.000" video="mainVideo-haskell" id="subtitle"]]
[[!template new="1" text="Another reason for favoring Emacs clients" start="00:13:41.144" video="mainVideo-haskell" id="subtitle"]]
[[!template text="over JavaScript clients is user freedom." start="00:13:45.464" video="mainVideo-haskell" id="subtitle"]]
[[!template text="Emacs is geared towards user freedom." start="00:13:49.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="It allows users maximum freedom to customize or mod Emacs." start="00:13:53.384" video="mainVideo-haskell" id="subtitle"]]
[[!template text="I think Emacs clients can be a way to fix JavaScript traps," start="00:14:01.664" video="mainVideo-haskell" id="subtitle"]]
[[!template text="like using user scripts to replace non-free JavaScript." start="00:14:07.264" video="mainVideo-haskell" id="subtitle"]]
[[!template text="There are tools to do that, for example, like Haketilo." start="00:14:14.344" video="mainVideo-haskell" id="subtitle"]]
[[!template text="Why write JavaScript replacement" start="00:14:19.584" video="mainVideo-haskell" id="subtitle"]]
[[!template text="if we can write Elisp replacement?" start="00:14:21.504" video="mainVideo-haskell" id="subtitle"]]
[[!template text="If we overwrite all kinds of front-ends in Emacs" start="00:14:25.264" video="mainVideo-haskell" id="subtitle"]]
[[!template text="for commonly-used web applications" start="00:14:31.784" video="mainVideo-haskell" id="subtitle"]]
[[!template text="like Reddit, Hacker News, what have you," start="00:14:34.504" video="mainVideo-haskell" id="subtitle"]]
[[!template text="then we have an Emacs app store" start="00:14:37.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="where we can just install these applications" start="00:14:40.904" video="mainVideo-haskell" id="subtitle"]]
[[!template text="and browse the web more freely." start="00:14:43.704" video="mainVideo-haskell" id="subtitle"]]
[[!template new="1" text="Back to hcel, which is the Emacs client I wrote." start="00:14:51.184" video="mainVideo-haskell" id="subtitle"]]
[[!template text="I tried to reuse as much of Emacs built-ins as possible," start="00:14:56.144" video="mainVideo-haskell" id="subtitle"]]
[[!template text="including eldoc, for showing documentation," start="00:14:59.184" video="mainVideo-haskell" id="subtitle"]]
[[!template text="xref for cross-referencer," start="00:15:03.144" video="mainVideo-haskell" id="subtitle"]]
[[!template text="compilation-mode for showing search results of identifiers," start="00:15:04.864" video="mainVideo-haskell" id="subtitle"]]
[[!template text="outline-mode for a hierarchical view" start="00:15:07.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="of package module identifiers," start="00:15:11.704" video="mainVideo-haskell" id="subtitle"]]
[[!template text="sort of a cursor-mode for highlighting identifiers," start="00:15:14.384" video="mainVideo-haskell" id="subtitle"]]
[[!template text="help-mode for displaying quick help for Haskell identifiers," start="00:15:18.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="integration with haddorg," start="00:15:26.144" video="mainVideo-haskell" id="subtitle"]]
[[!template text="which I will mention later, etc." start="00:15:27.704" video="mainVideo-haskell" id="subtitle"]]
[[!template text="It is available as hcel without the dot on GNU ELPA." start="00:15:31.304" video="mainVideo-haskell" id="subtitle"]]
[[!template text="Time for a demo." start="00:15:38.000" video="mainVideo-haskell" id="subtitle"]]
[[!template new="1" text="To start using hc.el, surprise surprise," start="00:15:40.184" video="mainVideo-haskell" id="subtitle"]]
[[!template text="we run the hcel command." start="00:15:42.584" video="mainVideo-haskell" id="subtitle"]]
[[!template text="We are presented with a list of packages" start="00:15:45.184" video="mainVideo-haskell" id="subtitle"]]
[[!template text="indexed by the hcel indexer." start="00:15:46.984" video="mainVideo-haskell" id="subtitle"]]
[[!template text="This is an outline mode," start="00:15:52.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="so we can tab to list all the modules" start="00:15:54.064" video="mainVideo-haskell" id="subtitle"]]
[[!template text="represented by the module path." start="00:15:58.824" video="mainVideo-haskell" id="subtitle"]]
[[!template text="We can further tab into the list of identifiers" start="00:16:01.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="declared in this module." start="00:16:03.504" video="mainVideo-haskell" id="subtitle"]]
[[!template text="Now it asks whether you want to open module source." start="00:16:05.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="This is because some module source code" start="00:16:09.184" video="mainVideo-haskell" id="subtitle"]]
[[!template text="can be quite large and it can take a bit of time." start="00:16:11.984" video="mainVideo-haskell" id="subtitle"]]
[[!template text="In this case, the control monad is quite small," start="00:16:14.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="so let's say yes." start="00:16:17.784" video="mainVideo-haskell" id="subtitle"]]
[[!template text="We see the list of identifiers." start="00:16:19.944" video="mainVideo-haskell" id="subtitle"]]
[[!template text="One can jump to an identifier forever." start="00:16:24.104" video="mainVideo-haskell" id="subtitle"]]
[[!template text="As you can see, the identifiers at points are highlighted." start="00:16:28.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="This can be particularly useful" start="00:16:33.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="in a large function declaration" start="00:16:36.224" video="mainVideo-haskell" id="subtitle"]]
[[!template text="where you come to see, for example," start="00:16:38.704" video="mainVideo-haskell" id="subtitle"]]
[[!template text="all the occurrences of an identifier" start="00:16:40.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="inside the body of the declaration." start="00:16:44.304" video="mainVideo-haskell" id="subtitle"]]
[[!template new="1" text="These are declarations" start="00:16:48.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="which in Haskell mode are listed in imenu." start="00:16:50.824" video="mainVideo-haskell" id="subtitle"]]
[[!template text="We can do the same here in hcel source mode." start="00:16:53.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="It lists all the declarations with their signature." start="00:17:00.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="Let's say we want to jump to this funny operator." start="00:17:06.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="It worked and you can also go back and forth" start="00:17:13.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="within the declarations by pressing "n" and "p"." start="00:17:20.424" video="mainVideo-haskell" id="subtitle"]]
[[!template text="Similarly, you can do something similar in the outline mode" start="00:17:26.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="by toggling the follow mode, just like in org-agenda." start="00:17:30.904" video="mainVideo-haskell" id="subtitle"]]
[[!template text="Let's turn it off." start="00:17:38.000" video="mainVideo-haskell" id="subtitle"]]
[[!template new="1" text="Now, how about find definition references?" start="00:17:40.224" video="mainVideo-haskell" id="subtitle"]]
[[!template text="Using xref," start="00:17:46.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="we can jump to the definition of Int and jump back." start="00:17:49.064" video="mainVideo-haskell" id="subtitle"]]
[[!template text="Jump to Maybe, jump back." start="00:17:53.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="Let's have a look at references of replicateM." start="00:17:56.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="There are plenty of them." start="00:18:01.024" video="mainVideo-haskell" id="subtitle"]]
[[!template text="Maybe we want to check out ghc-lib." start="00:18:03.464" video="mainVideo-haskell" id="subtitle"]]
[[!template text="Here are all the references" start="00:18:09.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="and you can of course jump to any of them in the results." start="00:18:11.344" video="mainVideo-haskell" id="subtitle"]]
[[!template text="Cool." start="00:18:16.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="You may have already noticed" start="00:18:19.000" video="mainVideo-haskell" id="subtitle"]]
[[!template new="1" text="the eldoc displaying the documentation" start="00:18:21.864" video="mainVideo-haskell" id="subtitle"]]
[[!template text="and signature of identifiers." start="00:18:27.184" video="mainVideo-haskell" id="subtitle"]]
[[!template text="For example, here it shows the signature of replicateM," start="00:18:34.904" video="mainVideo-haskell" id="subtitle"]]
[[!template text="where it is defined, and its documentation." start="00:18:44.104" video="mainVideo-haskell" id="subtitle"]]
[[!template text="We can bring up the eldoc buffer." start="00:18:47.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="In the eldoc buffer," start="00:18:56.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="there are also links to other identifiers," start="00:18:58.264" video="mainVideo-haskell" id="subtitle"]]
[[!template text="which takes you to the definition of these identifiers," start="00:19:00.184" video="mainVideo-haskell" id="subtitle"]]
[[!template text="like minBound." start="00:19:04.544" video="mainVideo-haskell" id="subtitle"]]
[[!template text="Apparently, this is not working." start="00:19:07.624" video="mainVideo-haskell" id="subtitle"]]
[[!template text="I'm pretty sure it maybe works." start="00:19:10.864" video="mainVideo-haskell" id="subtitle"]]
[[!template text="Let's go to nothing or just..." start="00:19:13.104" video="mainVideo-haskell" id="subtitle"]]
[[!template text="I think those didn't work because" start="00:19:17.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="the module source for those identifiers is not open." start="00:19:19.864" video="mainVideo-haskell" id="subtitle"]]
[[!template new="1" text="Of course, you can search" start="00:19:24.144" video="mainVideo-haskell" id="subtitle"]]
[[!template text="for any identifiers across all indexed packages" start="00:19:30.304" video="mainVideo-haskell" id="subtitle"]]
[[!template text="by invoking hcel-global-ids." start="00:19:33.024" video="mainVideo-haskell" id="subtitle"]]
[[!template text="Let's say we want to search for Read." start="00:19:38.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="We are presented with a list of results," start="00:19:42.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="which are identifiers starting with Read with capital R." start="00:19:47.464" video="mainVideo-haskell" id="subtitle"]]
[[!template text="They also show where they are defined" start="00:19:54.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="and the documentation, just like in eldoc." start="00:19:57.304" video="mainVideo-haskell" id="subtitle"]]
[[!template text="One can also directly jump to the identifier" start="00:20:07.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="in the mini-buffer results." start="00:20:13.944" video="mainVideo-haskell" id="subtitle"]]
[[!template text="For example, we want to check out this Read2" start="00:20:20.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="defined in base-4.12.0.0 Data.Functor.Classes" start="00:20:22.024" video="mainVideo-haskell" id="subtitle"]]
[[!template text="There we go." start="00:20:28.000" video="mainVideo-haskell" id="subtitle"]]
[[!template new="1" text="Another functionality of hcel" start="00:20:34.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="is the help buffer integration." start="00:20:37.864" video="mainVideo-haskell" id="subtitle"]]
[[!template text="We can do hcel-help and then let's say" start="00:20:41.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="we want to learn about the read type class." start="00:20:46.565" video="mainVideo-haskell" id="subtitle"]]
[[!template text="This is a help buffer" start="00:20:52.744" video="mainVideo-haskell" id="subtitle"]]
[[!template text="and you can jump to other definitions" start="00:20:55.184" video="mainVideo-haskell" id="subtitle"]]
[[!template text="within the help buffer" start="00:21:00.904" video="mainVideo-haskell" id="subtitle"]]
[[!template text="to read the documentation like readsPrec." start="00:21:02.464" video="mainVideo-haskell" id="subtitle"]]
[[!template text="It says Server version cannot be satistifed. Actual version." start="00:21:07.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="This means we need to tell hecl" start="00:21:11.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="that the server has the correct version." start="00:21:14.784" video="mainVideo-haskell" id="subtitle"]]
[[!template text="hecl-fetch-server-version." start="00:21:17.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="Wait a bit for it to update" start="00:21:21.744" video="mainVideo-haskell" id="subtitle"]]
[[!template text="the knowledge of the server version." start="00:21:25.704" video="mainVideo-haskell" id="subtitle"]]
[[!template text="Now you can follow the links, Read, readsPrec." start="00:21:27.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="You can do the "l" and "r" to navigate within the history." start="00:21:33.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="ReadS, ReadP." start="00:21:38.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="Just like in the help buffer for elisp code," start="00:21:43.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="you can jump to the definition." start="00:21:46.024" video="mainVideo-haskell" id="subtitle"]]
[[!template text="I believe that is everything, more or less." start="00:21:53.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="That concludes the demo." start="00:22:00.000" video="mainVideo-haskell" id="subtitle"]]
[[!template new="1" text="Now let's turn to haddorg," start="00:22:05.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="which is an Org backend for Haddock." start="00:22:07.144" video="mainVideo-haskell" id="subtitle"]]
[[!template text="Haddock is the documentation generator for Haskell packages." start="00:22:09.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="For example," start="00:22:13.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="the official Haskell package documentation website Hackage," start="00:22:15.144" video="mainVideo-haskell" id="subtitle"]]
[[!template text="all the documentation there is generated by Haddock" start="00:22:22.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="into the HTML format." start="00:22:25.904" video="mainVideo-haskell" id="subtitle"]]
[[!template text="Haddock has several backends" start="00:22:28.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="that convert the intermediate representation" start="00:22:31.424" video="mainVideo-haskell" id="subtitle"]]
[[!template text="called interface to various output formats," start="00:22:34.384" video="mainVideo-haskell" id="subtitle"]]
[[!template text="including HTML, LaTeX, and Hugo." start="00:22:37.064" video="mainVideo-haskell" id="subtitle"]]
[[!template text="HTML is the main format with a lot of features." start="00:22:41.864" video="mainVideo-haskell" id="subtitle"]]
[[!template text="LaTeX is less so, and I don't think it is widely used." start="00:22:44.904" video="mainVideo-haskell" id="subtitle"]]
[[!template text="Let's have a look at an HTML example." start="00:22:49.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="This is a PDF because these HTML files can be rather large" start="00:22:53.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="and slow down EWW significantly." start="00:23:01.184" video="mainVideo-haskell" id="subtitle"]]
[[!template text="It's faster to convert it to PDF" start="00:23:07.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="and read it from pdf-tools." start="00:23:10.264" video="mainVideo-haskell" id="subtitle"]]
[[!template text="Looks like this is as big as it goes." start="00:23:17.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="I hope you can still see it." start="00:23:20.864" video="mainVideo-haskell" id="subtitle"]]
[[!template text="Can I still enlarge it a bit more? Maybe." start="00:23:26.144" video="mainVideo-haskell" id="subtitle"]]
[[!template new="1" text="This is Servant.Server." start="00:23:30.144" video="mainVideo-haskell" id="subtitle"]]
[[!template text="It is a module in the servant-server package." start="00:23:33.064" video="mainVideo-haskell" id="subtitle"]]
[[!template text="It is a widely used package for writing servers." start="00:23:36.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="It starts with a heading, which is the name of the module," start="00:23:42.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="and the table of contents." start="00:23:49.904" video="mainVideo-haskell" id="subtitle"]]
[[!template text="Then a heading: Run an wai application from an API." start="00:23:52.784" video="mainVideo-haskell" id="subtitle"]]
[[!template text="Under this heading, there are all the relevant identifiers" start="00:23:56.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="that is concerned with running a WAI application from API," start="00:24:00.904" video="mainVideo-haskell" id="subtitle"]]
[[!template text="including serve, which is one of the main entry points" start="00:24:08.624" video="mainVideo-haskell" id="subtitle"]]
[[!template text="for a Servant.Server." start="00:24:13.304" video="mainVideo-haskell" id="subtitle"]]
[[!template text="It has a signature linkable to the other identifiers," start="00:24:15.624" video="mainVideo-haskell" id="subtitle"]]
[[!template text="the documentation," start="00:24:21.704" video="mainVideo-haskell" id="subtitle"]]
[[!template text="an example with a Haskell source code block." start="00:24:23.104" video="mainVideo-haskell" id="subtitle"]]
[[!template text="That's what HTML output looks like." start="00:24:26.744" video="mainVideo-haskell" id="subtitle"]]
[[!template new="1" text="As I mentioned," start="00:24:31.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="there are several downsides or drawbacks with that," start="00:24:34.024" video="mainVideo-haskell" id="subtitle"]]
[[!template text="like the HTML files can be huge and slow down EWW." start="00:24:35.904" video="mainVideo-haskell" id="subtitle"]]
[[!template text="Also, every module is an HTML of itself," start="00:24:41.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="and there's also an HTML for the package" start="00:24:46.224" video="mainVideo-haskell" id="subtitle"]]
[[!template text="with a list of all the modules." start="00:24:48.384" video="mainVideo-haskell" id="subtitle"]]
[[!template text="Whereas the Org backend" start="00:24:50.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="is better in that it is much more compact." start="00:24:54.744" video="mainVideo-haskell" id="subtitle"]]
[[!template text="All the modules under the same package" start="00:25:04.264" video="mainVideo-haskell" id="subtitle"]]
[[!template text="are included in one Org file" start="00:25:07.504" video="mainVideo-haskell" id="subtitle"]]
[[!template text="as sub-headings, level 2 headings." start="00:25:10.784" video="mainVideo-haskell" id="subtitle"]]
[[!template text="So, servant-server, Servant.Server, that is the module." start="00:25:13.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="So basically, this level 2 heading" start="00:25:19.504" video="mainVideo-haskell" id="subtitle"]]
[[!template text="contains all the information in this PDF." start="00:25:21.944" video="mainVideo-haskell" id="subtitle"]]
[[!template text="Run the WAI application from API, serve." start="00:25:25.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="It has a signature that links to other identifiers" start="00:25:29.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="and the documentation that's also linkable." start="00:25:39.224" video="mainVideo-haskell" id="subtitle"]]
[[!template text="The Haskell source block is now an Org source block," start="00:25:42.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="and you can do all sorts of interesting things" start="00:25:47.224" video="mainVideo-haskell" id="subtitle"]]
[[!template text="with it using org-babel." start="00:25:49.504" video="mainVideo-haskell" id="subtitle"]]
[[!template new="1" text="Let's check the links as server." start="00:25:52.744" video="mainVideo-haskell" id="subtitle"]]
[[!template text="Right, so the link works." start="00:25:56.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="Application, right, Request." start="00:26:00.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="It also supports cross-packaging package linking," start="00:26:05.384" video="mainVideo-haskell" id="subtitle"]]
[[!template text="so following the link to request" start="00:26:08.384" video="mainVideo-haskell" id="subtitle"]]
[[!template text="takes us from servant-server package Org documentation" start="00:26:12.304" video="mainVideo-haskell" id="subtitle"]]
[[!template text="to the WAI Org documentation." start="00:26:17.624" video="mainVideo-haskell" id="subtitle"]]
[[!template new="1" text="Another nice thing with Org documentation" start="00:26:24.784" video="mainVideo-haskell" id="subtitle"]]
[[!template text="is that you can use Org functions" start="00:26:27.544" video="mainVideo-haskell" id="subtitle"]]
[[!template text="like org-goto to jump to any identifiers." start="00:26:32.744" video="mainVideo-haskell" id="subtitle"]]
[[!template text="Let's say we want to jump to application." start="00:26:40.544" video="mainVideo-haskell" id="subtitle"]]
[[!template text="We have toApplication. So it jumpts to toApplication." start="00:26:45.904" video="mainVideo-haskell" id="subtitle"]]
[[!template text="I guess application is not an identifier," start="00:26:50.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="yes, it is more like a type alias," start="00:26:54.024" video="mainVideo-haskell" id="subtitle"]]
[[!template text="that's why we couldn't find it." start="00:26:55.824" video="mainVideo-haskell" id="subtitle"]]
[[!template text="So that is haddorg." start="00:26:58.664" video="mainVideo-haskell" id="subtitle"]]
[[!template text="And of course, I implemented a bit of integration" start="00:27:01.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="between haddorg and hcel" start="00:27:06.104" video="mainVideo-haskell" id="subtitle"]]
[[!template text="so that we can jump from one to the other." start="00:27:08.544" video="mainVideo-haskell" id="subtitle"]]
[[!template text="Let's go back to servant." start="00:27:11.304" video="mainVideo-haskell" id="subtitle"]]
[[!template text="Let's see, ServerT." start="00:27:15.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="Maybe we want to check out" start="00:27:24.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="the source code definition of ServerT." start="00:27:27.104" video="mainVideo-haskell" id="subtitle"]]
[[!template text="To find out exactly what sort of type alias it is," start="00:27:31.944" video="mainVideo-haskell" id="subtitle"]]
[[!template text="like what is the alias (or type synonym)" start="00:27:36.264" video="mainVideo-haskell" id="subtitle"]]
[[!template text="We run hcel-identifier-at-point--" start="00:27:43.184" video="mainVideo-haskell" id="subtitle"]]
[[!template text="sorry, hcel-haddorg-to-hcel-definition..." start="00:27:49.504" video="mainVideo-haskell" id="subtitle"]]
[[!template text="Oh, we have an HTTP error." start="00:27:52.344" video="mainVideo-haskell" id="subtitle"]]
[[!template text="Typ ServerT not found in module src/Servant/Server.hs" start="00:27:55.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="Why? Well, this is because" start="00:27:59.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="the HCEL server only understands," start="00:28:01.125" video="mainVideo-haskell" id="subtitle"]]
[[!template text="it only has knowledge of identifiers" start="00:28:04.944" video="mainVideo-haskell" id="subtitle"]]
[[!template text="that is defined in the original source file." start="00:28:07.824" video="mainVideo-haskell" id="subtitle"]]
[[!template text="So, it is not aware of, say," start="00:28:12.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="identifiers that are re-exported in the module." start="00:28:17.184" video="mainVideo-haskell" id="subtitle"]]
[[!template text="Most likely, Servant.Server module re-exports ServerT" start="00:28:21.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="from another module." start="00:28:25.824" video="mainVideo-haskell" id="subtitle"]]
[[!template text="We will probably have better luck" start="00:28:28.704" video="mainVideo-haskell" id="subtitle"]]
[[!template text="looking into some internal modules like this one." start="00:28:29.744" video="mainVideo-haskell" id="subtitle"]]
[[!template text="Let's try this type class HasContextEntry." start="00:28:35.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="So this time it worked." start="00:28:39.000" video="mainVideo-haskell" id="subtitle"]]
[[!template new="1" text="And, of course, we can go the other direction" start="00:28:42.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="from hecl to haddorg." start="00:28:44.344" video="mainVideo-haskell" id="subtitle"]]
[[!template text="Let's say if we want to display named context" start="00:28:48.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="in the haddorg documentation" start="00:28:51.584" video="mainVideo-haskell" id="subtitle"]]
[[!template text="so that we can read about, other identifiers documentation" start="00:28:54.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="that is related to named context." start="00:29:01.624" video="mainVideo-haskell" id="subtitle"]]
[[!template text="We do hecl-identifier-at-point-to-haddorg" start="00:29:04.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="And it does take us to the server-server old file." start="00:29:08.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="Okay." start="00:29:14.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="And that concludes my presentation." start="00:29:18.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="You can find hecl in GNU Elpa," start="00:29:21.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="and you can also find the source code," start="00:29:23.584" video="mainVideo-haskell" id="subtitle"]]
[[!template text="as well as the source of haddorg" start="00:29:25.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="and instructions on how to generate org documentation" start="00:29:27.464" video="mainVideo-haskell" id="subtitle"]]
[[!template text="using haddorg in my cgit instance." start="00:29:29.864" video="mainVideo-haskell" id="subtitle"]]
[[!template text="Thank you for your attention." start="00:29:33.000" video="mainVideo-haskell" id="subtitle"]]
[[!template text="I hope you enjoy the rest of the conference." start="00:29:36.784" video="mainVideo-haskell" id="subtitle"]]
[[!template text="Thank you." start="00:29:38.000" video="mainVideo-haskell" id="subtitle"]]
Questions or comments? Please e-mail [id@ypei.org](mailto:id@ypei.org?subject=Comment%20for%20EmacsConf%202022%20haskell%3A%20Haskell%20code%20exploration%20with%20Emacs)
<!-- End of emacsconf-publish-after-page -->
|