summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--2022/info/haskell-after.md456
-rw-r--r--2022/info/haskell-before.md43
2 files changed, 497 insertions, 2 deletions
diff --git a/2022/info/haskell-after.md b/2022/info/haskell-after.md
index 946b8696..8418fd81 100644
--- a/2022/info/haskell-after.md
+++ b/2022/info/haskell-after.md
@@ -1,6 +1,462 @@
<!-- 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"]]
+
+
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)
diff --git a/2022/info/haskell-before.md b/2022/info/haskell-before.md
index c40cf80f..7a652fe4 100644
--- a/2022/info/haskell-before.md
+++ b/2022/info/haskell-before.md
@@ -3,16 +3,55 @@ In this talk, Yuchen Pei demonstrates an Emacs package for exploring Haskell cod
The following image shows where the talk is in the schedule for Sat 2022-12-03. Solid lines show talks with Q&A via BigBlueButton. Dashed lines show talks with Q&A via IRC or Etherpad.<div class="schedule-in-context schedule-svg-container" data-slug="haskell">
-<svg width="800" height="150" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <title> Schedule for Saturday</title> <rect width="800" height="150" x="0" y="0" fill="white"></rect> <text font-size="10" fill="black" y="12" x="3"> Saturday</text> <a href="/2022/talks/sat-open" title="Saturday opening remarks" data-slug="sat-open"> <title> 9:00- 9:05 Saturday opening remarks</title> <rect x="0" y="15" opacity="0.5" width="7" height="59" stroke="black" stroke-dasharray="" fill="peachpuff"></rect> <g transform="translate(5,73)"> <text fill="black" x="0" y="0" font-size="10" transform="rotate(-90)"> sat-open</text></g></a> <a href="/2022/talks/journalism" title="Emacs journalism (or everything's a nail if you hit it with Emacs)" data-slug="journalism"> <title> 9:05- 9:25 Emacs journalism (or everything's a nail if you hit it with Emacs)</title> <rect x="7" y="15" opacity="0.5" width="31" height="59" stroke="black" stroke-dasharray="" fill="peachpuff"></rect> <g transform="translate(36,73)"> <text fill="black" x="0" y="0" font-size="10" transform="rotate(-90)"> journalism</text></g></a> <a href="/2022/talks/school" title="Back to school with Emacs" data-slug="school"> <title> 9:45- 9:55 Back to school with Emacs</title> <rect x="70" y="15" opacity="0.5" width="15" height="59" stroke="black" stroke-dasharray="5,5,5" fill="peachpuff"></rect> <g transform="translate(83,73)"> <text fill="black" x="0" y="0" font-size="10" transform="rotate(-90)"> school</text></g></a> <a href="/2022/talks/handwritten" title="How to incorporate handwritten notes into Emacs Orgmode" data-slug="handwritten"> <title> 10:05-10:15 How to incorporate handwritten notes into Emacs Orgmode</title> <rect x="101" y="15" opacity="0.5" width="15" height="59" stroke="black" stroke-dasharray="" fill="peachpuff"></rect> <g transform="translate(114,73)"> <text fill="black" x="0" y="0" font-size="10" transform="rotate(-90)"> handwritten</text></g></a> <a href="/2022/talks/science" title="Writing and organizing literature notes for scientific writing" data-slug="science"> <title> 10:45-11:05 Writing and organizing literature notes for scientific writing</title> <rect x="164" y="15" opacity="0.5" width="31" height="59" stroke="black" stroke-dasharray="" fill="peachpuff"></rect> <g transform="translate(193,73)"> <text fill="black" x="0" y="0" font-size="10" transform="rotate(-90)"> science</text></g></a> <a href="/2022/talks/buddy" title="The Emacs Buddy initiative" data-slug="buddy"> <title> 11:25-11:35 The Emacs Buddy initiative</title> <rect x="227" y="15" opacity="0.5" width="15" height="59" stroke="black" stroke-dasharray="5,5,5" fill="peachpuff"></rect> <g transform="translate(240,73)"> <text fill="black" x="0" y="0" font-size="10" transform="rotate(-90)"> buddy</text></g></a> <a href="/2022/talks/meetups" title="Attending and organizing Emacs meetups" data-slug="meetups"> <title> 1:00- 1:20 Attending and organizing Emacs meetups</title> <rect x="376" y="15" opacity="0.5" width="31" height="59" stroke="black" stroke-dasharray="" fill="peachpuff"></rect> <g transform="translate(405,73)"> <text fill="black" x="0" y="0" font-size="10" transform="rotate(-90)"> meetups</text></g></a> <a href="/2022/talks/buttons" title="Linking personal info with Hyperbole implicit buttons" data-slug="buttons"> <title> 1:40- 1:55 Linking personal info with Hyperbole implicit buttons</title> <rect x="439" y="15" opacity="0.5" width="23" height="59" stroke="black" stroke-dasharray="" fill="peachpuff"></rect> <g transform="translate(460,73)"> <text fill="black" x="0" y="0" font-size="10" transform="rotate(-90)"> buttons</text></g></a> <a href="/2022/talks/realestate" title="Real estate and Org table formulas" data-slug="realestate"> <title> 2:15- 2:40 Real estate and Org table formulas</title> <rect x="494" y="15" opacity="0.5" width="39" height="59" stroke="black" stroke-dasharray="5,5,5" fill="peachpuff"></rect> <g transform="translate(531,73)"> <text fill="black" x="0" y="0" font-size="10" transform="rotate(-90)"> realestate</text></g></a> <a href="/2022/talks/health" title="Health data journaling and visualization with Org Mode and gnuplot" data-slug="health"> <title> 3:00- 3:25 Health data journaling and visualization with Org Mode and gnuplot</title> <rect x="564" y="15" opacity="0.5" width="39" height="59" stroke="black" stroke-dasharray="" fill="peachpuff"></rect> <g transform="translate(601,73)"> <text fill="black" x="0" y="0" font-size="10" transform="rotate(-90)"> health</text></g></a> <a href="/2022/talks/jupyter" title="Edit live Jupyter notebook cells with Emacs" data-slug="jupyter"> <title> 3:45- 4:05 Edit live Jupyter notebook cells with Emacs</title> <rect x="635" y="15" opacity="0.5" width="31" height="59" stroke="black" stroke-dasharray="" fill="peachpuff"></rect> <g transform="translate(664,73)"> <text fill="black" x="0" y="0" font-size="10" transform="rotate(-90)"> jupyter</text></g></a> <a href="/2022/talks/sat-close" title="Saturday closing remarks" data-slug="sat-close"> <title> 4:50- 4:55 Saturday closing remarks</title> <rect x="737" y="15" opacity="0.5" width="7" height="59" stroke="black" stroke-dasharray="" fill="peachpuff"></rect> <g transform="translate(742,73)"> <text fill="black" x="0" y="0" font-size="10" transform="rotate(-90)"> sat-close</text></g></a> <a href="/2022/talks/treesitter" title="Tree-sitter beyond syntax highlighting" data-slug="treesitter"> <title> 10:00-10:15 Tree-sitter beyond syntax highlighting</title> <rect x="94" y="75" opacity="0.5" width="23" height="59" stroke="black" stroke-dasharray="5,5,5" fill="skyblue"></rect> <g transform="translate(115,133)"> <text fill="black" x="0" y="0" font-size="10" transform="rotate(-90)"> treesitter</text></g></a> <a href="/2022/talks/lspbridge" title="lsp-bridge: a smooth-as-butter asynchronous LSP client" data-slug="lspbridge"> <title> 10:25-10:45 lsp-bridge: a smooth-as-butter asynchronous LSP client</title> <rect x="133" y="75" opacity="0.5" width="31" height="59" stroke="black" stroke-dasharray="5,5,5" fill="skyblue"></rect> <g transform="translate(162,133)"> <text fill="black" x="0" y="0" font-size="10" transform="rotate(-90)"> lspbridge</text></g></a> <a href="/2022/talks/asmblox" title="asm-blox: a game based on WebAssembly that no one asked for" data-slug="asmblox"> <title> 10:55-11:15 asm-blox: a game based on WebAssembly that no one asked for</title> <rect x="180" y="75" opacity="0.5" width="31" height="59" stroke="black" stroke-dasharray="" fill="skyblue"></rect> <g transform="translate(209,133)"> <text fill="black" x="0" y="0" font-size="10" transform="rotate(-90)"> asmblox</text></g></a> <a href="/2022/talks/wayland" title="Emacs should become a Wayland compositor" data-slug="wayland"> <title> 11:25-11:35 Emacs should become a Wayland compositor</title> <rect x="227" y="75" opacity="0.5" width="15" height="59" stroke="black" stroke-dasharray="" fill="skyblue"></rect> <g transform="translate(240,133)"> <text fill="black" x="0" y="0" font-size="10" transform="rotate(-90)"> wayland</text></g></a> <a href="/2022/talks/sqlite" title="Using SQLite as a data source: a framework and an example" data-slug="sqlite"> <title> 1:00- 1:25 Using SQLite as a data source: a framework and an example</title> <rect x="376" y="75" opacity="0.5" width="39" height="59" stroke="black" stroke-dasharray="" fill="skyblue"></rect> <g transform="translate(413,133)"> <text fill="black" x="0" y="0" font-size="10" transform="rotate(-90)"> sqlite</text></g></a> <a href="/2022/talks/mail" title="Revisiting the anatomy of Emacs mail user agents" data-slug="mail"> <title> 1:50- 2:30 Revisiting the anatomy of Emacs mail user agents</title> <rect x="454" y="75" opacity="0.5" width="62" height="59" stroke="black" stroke-dasharray="" fill="skyblue"></rect> <g transform="translate(514,133)"> <text fill="black" x="0" y="0" font-size="10" transform="rotate(-90)"> mail</text></g></a> <a href="/2022/talks/maint" title="Maintaining the Maintainers: Attribution as an Economic Model for Open Source" data-slug="maint"> <title> 2:50- 3:10 Maintaining the Maintainers: Attribution as an Economic Model for Open Source</title> <rect x="549" y="75" opacity="0.5" width="31" height="59" stroke="black" stroke-dasharray="" fill="skyblue"></rect> <g transform="translate(578,133)"> <text fill="black" x="0" y="0" font-size="10" transform="rotate(-90)"> maint</text></g></a> <a href="/2022/talks/eev" title="Bidirectional links with eev" data-slug="eev"> <title> 3:35- 3:40 Bidirectional links with eev</title> <rect x="619" y="75" opacity="0.5" width="7" height="59" stroke="black" stroke-dasharray="5,5,5" fill="skyblue"></rect> <g transform="translate(624,133)"> <text fill="black" x="0" y="0" font-size="10" transform="rotate(-90)"> eev</text></g></a> <a href="/2022/talks/python" title="Short hyperlinks to Python docs" data-slug="python"> <title> 3:50- 3:55 Short hyperlinks to Python docs</title> <rect x="643" y="75" opacity="0.5" width="7" height="59" stroke="black" stroke-dasharray="5,5,5" fill="skyblue"></rect> <g transform="translate(648,133)"> <text fill="black" x="0" y="0" font-size="10" transform="rotate(-90)"> python</text></g></a> <a href="/2022/talks/haskell" title="Haskell code exploration with Emacs" data-slug="haskell"> <title> 4:05- 4:35 Haskell code exploration with Emacs</title> <rect stroke-width="3" x="666" y="75" opacity="0.8" width="47" height="59" stroke="black" stroke-dasharray="" fill="skyblue"></rect> <g transform="translate(711,133)"> <text font-weight="bold" fill="black" x="0" y="0" font-size="10" transform="rotate(-90)"> haskell</text></g></a> <g transform="translate(0,15)"> <line stroke="darkgray" x1="0" y1="0" x2="0" y2="120"></line> <text fill="black" x="0" y="133" font-size="10" text-anchor="left"> 9 AM</text></g> <g transform="translate(94,15)"> <line stroke="darkgray" x1="0" y1="0" x2="0" y2="120"></line> <text fill="black" x="0" y="133" font-size="10" text-anchor="left"> 10 AM</text></g> <g transform="translate(188,15)"> <line stroke="darkgray" x1="0" y1="0" x2="0" y2="120"></line> <text fill="black" x="0" y="133" font-size="10" text-anchor="left"> 11 AM</text></g> <g transform="translate(282,15)"> <line stroke="darkgray" x1="0" y1="0" x2="0" y2="120"></line> <text fill="black" x="0" y="133" font-size="10" text-anchor="left"> 12 PM</text></g> <g transform="translate(376,15)"> <line stroke="darkgray" x1="0" y1="0" x2="0" y2="120"></line> <text fill="black" x="0" y="133" font-size="10" text-anchor="left"> 1 PM</text></g> <g transform="translate(470,15)"> <line stroke="darkgray" x1="0" y1="0" x2="0" y2="120"></line> <text fill="black" x="0" y="133" font-size="10" text-anchor="left"> 2 PM</text></g> <g transform="translate(564,15)"> <line stroke="darkgray" x1="0" y1="0" x2="0" y2="120"></line> <text fill="black" x="0" y="133" font-size="10" text-anchor="left"> 3 PM</text></g> <g transform="translate(658,15)"> <line stroke="darkgray" x1="0" y1="0" x2="0" y2="120"></line> <text fill="black" x="0" y="133" font-size="10" text-anchor="left"> 4 PM</text></g> <g transform="translate(752,15)"> <line stroke="darkgray" x1="0" y1="0" x2="0" y2="120"></line> <text fill="black" x="0" y="133" font-size="10" text-anchor="left"> 5 PM</text></g></svg>
+<svg width="800" height="150" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> <title> Schedule for Saturday</title> <rect width="800" height="150" x="0" y="0" fill="white"></rect> <text font-size="10" fill="black" y="12" x="3"> Saturday</text> <a href="/2022/talks/sat-open" title="Saturday opening remarks" data-slug="sat-open"> <title> 9:00- 9:05 Saturday opening remarks</title> <rect x="0" y="15" opacity="0.5" width="7" height="59" stroke="black" stroke-dasharray="" fill="peachpuff"></rect> <g transform="translate(5,73)"> <text fill="black" x="0" y="0" font-size="10" transform="rotate(-90)"> sat-open</text></g></a> <a href="/2022/talks/journalism" title="Emacs journalism (or everything's a nail if you hit it with Emacs)" data-slug="journalism"> <title> 9:05- 9:25 Emacs journalism (or everything's a nail if you hit it with Emacs)</title> <rect x="7" y="15" opacity="0.5" width="31" height="59" stroke="black" stroke-dasharray="" fill="peachpuff"></rect> <g transform="translate(36,73)"> <text fill="black" x="0" y="0" font-size="10" transform="rotate(-90)"> journalism</text></g></a> <a href="/2022/talks/school" title="Back to school with Emacs" data-slug="school"> <title> 9:45- 9:55 Back to school with Emacs</title> <rect x="70" y="15" opacity="0.5" width="15" height="59" stroke="black" stroke-dasharray="5,5,5" fill="peachpuff"></rect> <g transform="translate(83,73)"> <text fill="black" x="0" y="0" font-size="10" transform="rotate(-90)"> school</text></g></a> <a href="/2022/talks/handwritten" title="How to incorporate handwritten notes into Emacs Orgmode" data-slug="handwritten"> <title> 10:05-10:15 How to incorporate handwritten notes into Emacs Orgmode</title> <rect x="101" y="15" opacity="0.5" width="15" height="59" stroke="black" stroke-dasharray="" fill="peachpuff"></rect> <g transform="translate(114,73)"> <text fill="black" x="0" y="0" font-size="10" transform="rotate(-90)"> handwritten</text></g></a> <a href="/2022/talks/science" title="Writing and organizing literature notes for scientific writing" data-slug="science"> <title> 10:45-11:05 Writing and organizing literature notes for scientific writing</title> <rect x="164" y="15" opacity="0.5" width="31" height="59" stroke="black" stroke-dasharray="" fill="peachpuff"></rect> <g transform="translate(193,73)"> <text fill="black" x="0" y="0" font-size="10" transform="rotate(-90)"> science</text></g></a> <a href="/2022/talks/buddy" title="The Emacs Buddy initiative" data-slug="buddy"> <title> 11:25-11:35 The Emacs Buddy initiative</title> <rect x="227" y="15" opacity="0.5" width="15" height="59" stroke="black" stroke-dasharray="5,5,5" fill="peachpuff"></rect> <g transform="translate(240,73)"> <text fill="black" x="0" y="0" font-size="10" transform="rotate(-90)"> buddy</text></g></a> <a href="/2022/talks/meetups" title="Attending and organizing Emacs meetups" data-slug="meetups"> <title> 1:00- 1:20 Attending and organizing Emacs meetups</title> <rect x="376" y="15" opacity="0.5" width="31" height="59" stroke="black" stroke-dasharray="" fill="peachpuff"></rect> <g transform="translate(405,73)"> <text fill="black" x="0" y="0" font-size="10" transform="rotate(-90)"> meetups</text></g></a> <a href="/2022/talks/buttons" title="Linking personal info with Hyperbole implicit buttons" data-slug="buttons"> <title> 1:40- 1:55 Linking personal info with Hyperbole implicit buttons</title> <rect x="439" y="15" opacity="0.5" width="23" height="59" stroke="black" stroke-dasharray="" fill="peachpuff"></rect> <g transform="translate(460,73)"> <text fill="black" x="0" y="0" font-size="10" transform="rotate(-90)"> buttons</text></g></a> <a href="/2022/talks/realestate" title="Real estate and Org table formulas" data-slug="realestate"> <title> 2:15- 2:40 Real estate and Org table formulas</title> <rect x="494" y="15" opacity="0.5" width="39" height="59" stroke="black" stroke-dasharray="5,5,5" fill="peachpuff"></rect> <g transform="translate(531,73)"> <text fill="black" x="0" y="0" font-size="10" transform="rotate(-90)"> realestate</text></g></a> <a href="/2022/talks/health" title="Health data journaling and visualization with Org Mode and gnuplot" data-slug="health"> <title> 3:00- 3:25 Health data journaling and visualization with Org Mode and gnuplot</title> <rect x="564" y="15" opacity="0.5" width="39" height="59" stroke="black" stroke-dasharray="" fill="peachpuff"></rect> <g transform="translate(601,73)"> <text fill="black" x="0" y="0" font-size="10" transform="rotate(-90)"> health</text></g></a> <a href="/2022/talks/jupyter" title="Edit live Jupyter notebook cells with Emacs" data-slug="jupyter"> <title> 3:45- 4:05 Edit live Jupyter notebook cells with Emacs</title> <rect x="635" y="15" opacity="0.5" width="31" height="59" stroke="black" stroke-dasharray="" fill="peachpuff"></rect> <g transform="translate(664,73)"> <text fill="black" x="0" y="0" font-size="10" transform="rotate(-90)"> jupyter</text></g></a> <a href="/2022/talks/sat-close" title="Saturday closing remarks" data-slug="sat-close"> <title> 4:50- 4:55 Saturday closing remarks</title> <rect x="737" y="15" opacity="0.5" width="7" height="59" stroke="black" stroke-dasharray="" fill="peachpuff"></rect> <g transform="translate(742,73)"> <text fill="black" x="0" y="0" font-size="10" transform="rotate(-90)"> sat-close</text></g></a> <a href="/2022/talks/treesitter" title="Tree-sitter beyond syntax highlighting" data-slug="treesitter"> <title> 10:00-10:15 Tree-sitter beyond syntax highlighting</title> <rect x="94" y="75" opacity="0.5" width="23" height="59" stroke="black" stroke-dasharray="5,5,5" fill="skyblue"></rect> <g transform="translate(115,133)"> <text fill="black" x="0" y="0" font-size="10" transform="rotate(-90)"> treesitter</text></g></a> <a href="/2022/talks/lspbridge" title="lsp-bridge: a smooth-as-butter asynchronous LSP client" data-slug="lspbridge"> <title> 10:25-10:45 lsp-bridge: a smooth-as-butter asynchronous LSP client</title> <rect x="133" y="75" opacity="0.5" width="31" height="59" stroke="black" stroke-dasharray="5,5,5" fill="skyblue"></rect> <g transform="translate(162,133)"> <text fill="black" x="0" y="0" font-size="10" transform="rotate(-90)"> lspbridge</text></g></a> <a href="/2022/talks/asmblox" title="asm-blox: a game based on WebAssembly that no one asked for" data-slug="asmblox"> <title> 10:55-11:15 asm-blox: a game based on WebAssembly that no one asked for</title> <rect x="180" y="75" opacity="0.5" width="31" height="59" stroke="black" stroke-dasharray="" fill="skyblue"></rect> <g transform="translate(209,133)"> <text fill="black" x="0" y="0" font-size="10" transform="rotate(-90)"> asmblox</text></g></a> <a href="/2022/talks/wayland" title="Emacs should become a Wayland compositor" data-slug="wayland"> <title> 11:25-11:35 Emacs should become a Wayland compositor</title> <rect x="227" y="75" opacity="0.5" width="15" height="59" stroke="black" stroke-dasharray="" fill="skyblue"></rect> <g transform="translate(240,133)"> <text fill="black" x="0" y="0" font-size="10" transform="rotate(-90)"> wayland</text></g></a> <a href="/2022/talks/sqlite" title="Using SQLite as a data source: a framework and an example" data-slug="sqlite"> <title> 1:00- 1:25 Using SQLite as a data source: a framework and an example</title> <rect x="376" y="75" opacity="0.5" width="39" height="59" stroke="black" stroke-dasharray="" fill="skyblue"></rect> <g transform="translate(413,133)"> <text fill="black" x="0" y="0" font-size="10" transform="rotate(-90)"> sqlite</text></g></a> <a href="/2022/talks/mail" title="Revisiting the anatomy of Emacs mail user agents" data-slug="mail"> <title> 1:50- 2:30 Revisiting the anatomy of Emacs mail user agents</title> <rect x="454" y="75" opacity="0.5" width="62" height="59" stroke="black" stroke-dasharray="" fill="skyblue"></rect> <g transform="translate(514,133)"> <text fill="black" x="0" y="0" font-size="10" transform="rotate(-90)"> mail</text></g></a> <a href="/2022/talks/maint" title="Maintaining the Maintainers: Attribution as an Economic Model for Open Source" data-slug="maint"> <title> 2:50- 3:10 Maintaining the Maintainers: Attribution as an Economic Model for Open Source</title> <rect x="549" y="75" opacity="0.5" width="31" height="59" stroke="black" stroke-dasharray="5,5,5" fill="skyblue"></rect> <g transform="translate(578,133)"> <text fill="black" x="0" y="0" font-size="10" transform="rotate(-90)"> maint</text></g></a> <a href="/2022/talks/eev" title="Bidirectional links with eev" data-slug="eev"> <title> 3:35- 3:40 Bidirectional links with eev</title> <rect x="619" y="75" opacity="0.5" width="7" height="59" stroke="black" stroke-dasharray="5,5,5" fill="skyblue"></rect> <g transform="translate(624,133)"> <text fill="black" x="0" y="0" font-size="10" transform="rotate(-90)"> eev</text></g></a> <a href="/2022/talks/haskell" title="Haskell code exploration with Emacs" data-slug="haskell"> <title> 4:05- 4:35 Haskell code exploration with Emacs</title> <rect stroke-width="3" x="666" y="75" opacity="0.8" width="47" height="59" stroke="black" stroke-dasharray="" fill="skyblue"></rect> <g transform="translate(711,133)"> <text font-weight="bold" fill="black" x="0" y="0" font-size="10" transform="rotate(-90)"> haskell</text></g></a> <g transform="translate(0,15)"> <line stroke="darkgray" x1="0" y1="0" x2="0" y2="120"></line> <text fill="black" x="0" y="133" font-size="10" text-anchor="left"> 9 AM</text></g> <g transform="translate(94,15)"> <line stroke="darkgray" x1="0" y1="0" x2="0" y2="120"></line> <text fill="black" x="0" y="133" font-size="10" text-anchor="left"> 10 AM</text></g> <g transform="translate(188,15)"> <line stroke="darkgray" x1="0" y1="0" x2="0" y2="120"></line> <text fill="black" x="0" y="133" font-size="10" text-anchor="left"> 11 AM</text></g> <g transform="translate(282,15)"> <line stroke="darkgray" x1="0" y1="0" x2="0" y2="120"></line> <text fill="black" x="0" y="133" font-size="10" text-anchor="left"> 12 PM</text></g> <g transform="translate(376,15)"> <line stroke="darkgray" x1="0" y1="0" x2="0" y2="120"></line> <text fill="black" x="0" y="133" font-size="10" text-anchor="left"> 1 PM</text></g> <g transform="translate(470,15)"> <line stroke="darkgray" x1="0" y1="0" x2="0" y2="120"></line> <text fill="black" x="0" y="133" font-size="10" text-anchor="left"> 2 PM</text></g> <g transform="translate(564,15)"> <line stroke="darkgray" x1="0" y1="0" x2="0" y2="120"></line> <text fill="black" x="0" y="133" font-size="10" text-anchor="left"> 3 PM</text></g> <g transform="translate(658,15)"> <line stroke="darkgray" x1="0" y1="0" x2="0" y2="120"></line> <text fill="black" x="0" y="133" font-size="10" text-anchor="left"> 4 PM</text></g> <g transform="translate(752,15)"> <line stroke="darkgray" x1="0" y1="0" x2="0" y2="120"></line> <text fill="black" x="0" y="133" font-size="10" text-anchor="left"> 5 PM</text></g></svg>
</div>
[[!toc ]]
Format: 30-min talk followed by live Q&A (<https://emacsconf.org/current/haskell/room>)
Etherpad: <https://pad.emacsconf.org/2022-haskell>
Discuss on IRC: [#emacsconf-dev](https://chat.emacsconf.org/?join=emacsconf,emacsconf-dev)
-Status: Talk captioned
+Status: Now playing on the conference livestream
<div>Times in different timezones:</div><div class="times" start="2022-12-03T21:05:00Z" end="2022-12-03T21:35:00Z"><div class="conf-time">Saturday, Dec 3 2022, ~4:05 PM - 4:35 PM EST (US/Eastern)</div><div class="others"><div>which is the same as:</div>Saturday, Dec 3 2022, ~3:05 PM - 3:35 PM CST (US/Central)<br />Saturday, Dec 3 2022, ~2:05 PM - 2:35 PM MST (US/Mountain)<br />Saturday, Dec 3 2022, ~1:05 PM - 1:35 PM PST (US/Pacific)<br />Saturday, Dec 3 2022, ~9:05 PM - 9:35 PM UTC <br />Saturday, Dec 3 2022, ~10:05 PM - 10:35 PM CET (Europe/Paris)<br />Saturday, Dec 3 2022, ~11:05 PM - 11:35 PM EET (Europe/Athens)<br />Sunday, Dec 4 2022, ~2:35 AM - 3:05 AM IST (Asia/Kolkata)<br />Sunday, Dec 4 2022, ~5:05 AM - 5:35 AM +08 (Asia/Singapore)<br />Sunday, Dec 4 2022, ~6:05 AM - 6:35 AM JST (Asia/Tokyo)</div></div><div><a href="/2022/watch/dev/">Find out how to watch and participate</a></div>
+[[!template id="vid" vidid="haskell-mainVideo" src="https://media.emacsconf.org/2022/emacsconf-2022-haskell--haskell-code-exploration-with-emacs--yuchen-pei--main.webm" poster="https://media.emacsconf.org/2022/emacsconf-2022-haskell--haskell-code-exploration-with-emacs--yuchen-pei--main.png" captions="""<track label="English" kind="captions" srclang="en" src="/2022/captions/emacsconf-2022-haskell--haskell-code-exploration-with-emacs--yuchen-pei--main.vtt" default />"""
+size="50M" duration="29:40" other_resources="""[Download --main.webm (47MB)](https://media.emacsconf.org/2022/emacsconf-2022-haskell--haskell-code-exploration-with-emacs--yuchen-pei--main.webm)
+[Download --main.vtt](https://media.emacsconf.org/2022/emacsconf-2022-haskell--haskell-code-exploration-with-emacs--yuchen-pei--main.vtt)
+[Download --main--chapters.vtt](https://media.emacsconf.org/2022/emacsconf-2022-haskell--haskell-code-exploration-with-emacs--yuchen-pei--main--chapters.vtt)
+[View transcript](https://emacsconf.org/2022/talks/haskell#haskell-mainVideo-transcript)
+[View on Toobnix](https://toobnix.org/w/6u6Pd9P8zcbwfFVXNHYzUz)
+"""]]
+[[!template id="chapters" vidid="haskell-mainVideo" data="""
+00:00:00.000 What is Haskell?
+00:30.520 Parts of a Haskell program
+01:33.640 Example of Haskell source code
+02:13.400 Writing Haskell like Lisp
+02:37.160 What is a code explorer?
+03:53.760 Prior art
+04:56.240 Haskell mode
+05:46.080 Jumping to declarations
+06:43.560 Finding references
+07:24.840 The Haskell language server
+08:20.520 Hoogle and Hackage
+08:54.960 Haskell Code Explorer
+09:34.600 Demo of Haskell Code Explorer
+10:42.080 Learning about monads
+12:35.480 Web client
+13:39.920 User freedom
+14:47.800 hc.el
+15:38.560 Demo
+16:46.520 Declarations
+17:38.920 Finding definitions and references
+18:19.160 Eldoc
+19:22.360 Searching for identifiers
+20:32.560 Help buffer integration
+22:01.440 Haddock
+23:28.840 Servant
+24:30.480 Org
+25:50.320 Links
+26:19.280 Navigation
+28:41.160 Going the other direction
+
+"""]]
# Description