summaryrefslogtreecommitdiffstats
path: root/2022/info/haskell-after.md
diff options
context:
space:
mode:
Diffstat (limited to '2022/info/haskell-after.md')
-rw-r--r--2022/info/haskell-after.md466
1 files changed, 466 insertions, 0 deletions
diff --git a/2022/info/haskell-after.md b/2022/info/haskell-after.md
new file mode 100644
index 00000000..e9e454fb
--- /dev/null
+++ b/2022/info/haskell-after.md
@@ -0,0 +1,466 @@
+<!-- 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 &quot;Read&quot;""" start="00:12:09.584" video="mainVideo-haskell" id="subtitle"]]
+[[!template text="""I think this is the &quot;Read&quot; 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 &quot;n&quot; and &quot;p&quot;.""" 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 &quot;l&quot; and &quot;r&quot; 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"]]
+
+
+
+Captioner: anush
+
+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 -->