diff options
Diffstat (limited to '')
-rw-r--r-- | 2022/info/haskell-after.md | 904 |
1 files changed, 453 insertions, 451 deletions
diff --git a/2022/info/haskell-after.md b/2022/info/haskell-after.md index 8418fd81..1a00c5a0 100644 --- a/2022/info/haskell-after.md +++ b/2022/info/haskell-after.md @@ -4,459 +4,461 @@ <a name="haskell-mainVideo-transcript"></a> # Transcript -[[!template new="1" text="Today, I will talk about Haskell code exploration for Emacs." start="00:00:00.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="What is Haskell? It is a purely functional language." start="00:00:03.500" video="mainVideo-haskell" id="subtitle"]] -[[!template text="For example, every value in Haskell is immutable." start="00:00:06.500" video="mainVideo-haskell" id="subtitle"]] -[[!template text="And it is the main compiler of Haskell, GHC." start="00:00:09.500" video="mainVideo-haskell" id="subtitle"]] -[[!template text="It provides API for the whole compilation pipeline." start="00:00:13.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="For example, the tools mentioned in this talk," start="00:00:16.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="including hcel and haddorg," start="00:00:18.424" video="mainVideo-haskell" id="subtitle"]] -[[!template text="they use, they heavily utilize the GHC front-end API" start="00:00:20.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="for parsing and understanding" start="00:00:24.500" video="mainVideo-haskell" id="subtitle"]] -[[!template text="the identifiers in Haskell source files." start="00:00:26.744" video="mainVideo-haskell" id="subtitle"]] -[[!template text="Roughly speaking," start="00:00:29.500" video="mainVideo-haskell" id="subtitle"]] -[[!template new="1" text="a Haskell program consists of several parts." start="00:00:31.544" video="mainVideo-haskell" id="subtitle"]] -[[!template text="it begins with some front matters, including," start="00:00:34.664" video="mainVideo-haskell" id="subtitle"]] -[[!template text="for example, language extensions," start="00:00:37.064" video="mainVideo-haskell" id="subtitle"]] -[[!template text="which are optional language features one might want to use" start="00:00:40.024" video="mainVideo-haskell" id="subtitle"]] -[[!template text="for convenience." start="00:00:44.064" video="mainVideo-haskell" id="subtitle"]] -[[!template text="The front matters also contain module exports." start="00:00:48.464" video="mainVideo-haskell" id="subtitle"]] -[[!template text="So for example, here we define," start="00:00:52.500" video="mainVideo-haskell" id="subtitle"]] -[[!template text="we declare module F2Md.Config" start="00:00:55.784" video="mainVideo-haskell" id="subtitle"]] -[[!template text="for this Haskell source file," start="00:00:58.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="which exports these four identifiers" start="00:01:00.984" video="mainVideo-haskell" id="subtitle"]] -[[!template text="that other source files can use when importing F2Md.Config." start="00:01:03.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="And the next will be" start="00:01:07.500" video="mainVideo-haskell" id="subtitle"]] -[[!template text="a block of imports so that we can use libraries" start="00:01:10.784" video="mainVideo-haskell" id="subtitle"]] -[[!template text="and identifiers in these libraries." start="00:01:14.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="The bulk of a Haskell source file normally is" start="00:01:17.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="a list of declarations," start="00:01:21.744" video="mainVideo-haskell" id="subtitle"]] -[[!template text="including values, types, and instances, and so on." start="00:01:23.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="The difference between a value and a type is that" start="00:01:26.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="the type of a value is a type," start="00:01:29.184" video="mainVideo-haskell" id="subtitle"]] -[[!template text="and the type of a type is a kind." start="00:01:30.500" video="mainVideo-haskell" id="subtitle"]] -[[!template new="1" text="For example, here's a small block of Haskell source code." start="00:01:34.064" video="mainVideo-haskell" id="subtitle"]] -[[!template text="We define Range type" start="00:01:38.584" video="mainVideo-haskell" id="subtitle"]] -[[!template text="from a lower-end integer to a higher-end integer." start="00:01:41.504" video="mainVideo-haskell" id="subtitle"]] -[[!template text="We also declare a value r of the type Range," start="00:01:45.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="which is Range from 2 to 7," start="00:01:51.464" video="mainVideo-haskell" id="subtitle"]] -[[!template text="because in Haskell, we like to--" start="00:01:54.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="by default, functions can be curried," start="00:02:01.104" video="mainVideo-haskell" id="subtitle"]] -[[!template text="which basically means, by default, we want to utilize" start="00:02:04.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="the partial application of functions." start="00:02:09.904" video="mainVideo-haskell" id="subtitle"]] -[[!template text="We don't require parens surrounding arguments" start="00:02:12.000" video="mainVideo-haskell" id="subtitle"]] -[[!template new="1" text="when invoking a function." start="00:02:17.384" video="mainVideo-haskell" id="subtitle"]] -[[!template text="That makes it possible, if you want," start="00:02:19.464" video="mainVideo-haskell" id="subtitle"]] -[[!template text="to write Haskell like Lisp" start="00:02:22.725" video="mainVideo-haskell" id="subtitle"]] -[[!template text="by adding a bit of redundant parens." start="00:02:25.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="So for example," start="00:02:28.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="here are two blocks of code, one Lisp, one Haskell," start="00:02:30.144" video="mainVideo-haskell" id="subtitle"]] -[[!template text="and they look quite similar to each other." start="00:02:33.784" video="mainVideo-haskell" id="subtitle"]] -[[!template text="What is a code explorer?" start="00:02:36.000" video="mainVideo-haskell" id="subtitle"]] -[[!template new="1" text="A code explorer is a tool" start="00:02:38.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="to browse its code base to its code comprehension." start="00:02:39.544" video="mainVideo-haskell" id="subtitle"]] -[[!template text="Code explorer commonly comes with" start="00:02:42.724" video="mainVideo-haskell" id="subtitle"]] -[[!template text="several functionalities or features," start="00:02:45.424" video="mainVideo-haskell" id="subtitle"]] -[[!template text="including a cross-referencer," start="00:02:47.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="which allows going to definitions of an identifier at points" start="00:02:49.344" video="mainVideo-haskell" id="subtitle"]] -[[!template text="or looking up references of an identifier," start="00:02:53.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="like where it is used." start="00:02:56.544" video="mainVideo-haskell" id="subtitle"]] -[[!template text="So the example in Emacs would be xref." start="00:02:58.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="Code explorer also would be able to show you" start="00:03:04.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="documentation and signatures of identifiers at points." start="00:03:07.704" video="mainVideo-haskell" id="subtitle"]] -[[!template text="In Emacs, that would be eldoc." start="00:03:10.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="It also commonly allows you to search for identifiers." start="00:03:13.984" video="mainVideo-haskell" id="subtitle"]] -[[!template text="Something like that in Emacs" start="00:03:17.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="could be describe-function and find-function." start="00:03:19.984" video="mainVideo-haskell" id="subtitle"]] -[[!template text="Code explorer is normally" start="00:03:22.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="quite often implemented in two parts," start="00:03:24.784" video="mainVideo-haskell" id="subtitle"]] -[[!template text="the indexer and the server," start="00:03:27.464" video="mainVideo-haskell" id="subtitle"]] -[[!template text="where the indexer parses the source code files," start="00:03:28.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="indexes the identifiers," start="00:03:32.584" video="mainVideo-haskell" id="subtitle"]] -[[!template text="and stores the information of identifiers" start="00:03:34.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="like the definition, size, and the currencies," start="00:03:36.384" video="mainVideo-haskell" id="subtitle"]] -[[!template text="either in databases or in files." start="00:03:38.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="The other part is the server," start="00:03:42.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="which uses the database created by the indexer" start="00:03:44.544" video="mainVideo-haskell" id="subtitle"]] -[[!template text="to serve the information of the identifier." start="00:03:49.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="Before I present my solution to code exploring," start="00:03:53.104" video="mainVideo-haskell" id="subtitle"]] -[[!template new="1" text="some description of prior art is in order." start="00:03:57.104" video="mainVideo-haskell" id="subtitle"]] -[[!template text="There are several tools that you can use" start="00:04:01.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="to aid code exploration," start="00:04:05.384" video="mainVideo-haskell" id="subtitle"]] -[[!template text="including tech-based tools like hasktags and hs-tags." start="00:04:08.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="The limitation with these tools" start="00:04:13.544" video="mainVideo-haskell" id="subtitle"]] -[[!template text="is they are focused on the current projects only" start="00:04:15.584" video="mainVideo-haskell" id="subtitle"]] -[[!template text="and do not work" start="00:04:18.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="for cross-packaging reference and definition." start="00:04:19.704" video="mainVideo-haskell" id="subtitle"]] -[[!template text="Another problem with the tag-based tools is" start="00:04:26.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="they might not handle symbols with the same name properly." start="00:04:31.045" video="mainVideo-haskell" id="subtitle"]] -[[!template text="Sometimes they get confused," start="00:04:34.784" video="mainVideo-haskell" id="subtitle"]] -[[!template text="and they ask you to choose which definition," start="00:04:36.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="what is the correct definition site," start="00:04:43.424" video="mainVideo-haskell" id="subtitle"]] -[[!template text="even though the occurrence of the symbol" start="00:04:46.024" video="mainVideo-haskell" id="subtitle"]] -[[!template text="or the symbol at point has only one definition ambiguously." start="00:04:49.344" video="mainVideo-haskell" id="subtitle"]] -[[!template text="Another tool is the haskell-mode." start="00:04:55.000" video="mainVideo-haskell" id="subtitle"]] -[[!template new="1" text="It has some limited support for eldoc" start="00:04:58.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="by displaying the signature of an identifier at points," start="00:05:02.784" video="mainVideo-haskell" id="subtitle"]] -[[!template text="but the identifier has to be something" start="00:05:06.704" video="mainVideo-haskell" id="subtitle"]] -[[!template text="that is commonly known or sort of built-in" start="00:05:11.864" video="mainVideo-haskell" id="subtitle"]] -[[!template text="or come from the base library of Haskell." start="00:05:15.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="So for example," start="00:05:18.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="it works for common functions like head and tail." start="00:05:20.344" video="mainVideo-haskell" id="subtitle"]] -[[!template text="And you can see that the signature is displayed here." start="00:05:24.344" video="mainVideo-haskell" id="subtitle"]] -[[!template text="However, it does not work for," start="00:05:27.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="let's say, IO. IO is a type." start="00:05:29.664" video="mainVideo-haskell" id="subtitle"]] -[[!template text="Maybe that's the reason." start="00:05:31.904" video="mainVideo-haskell" id="subtitle"]] -[[!template text="Let's find another function" start="00:05:33.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="that's not from the base library." start="00:05:37.424" video="mainVideo-haskell" id="subtitle"]] -[[!template text="toJSON is from the Aeson library," start="00:05:40.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="so no signature is displayed here." start="00:05:42.000" video="mainVideo-haskell" id="subtitle"]] -[[!template new="1" text="It also provides" start="00:05:47.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="some sort of goto-declaration functionality" start="00:05:51.264" video="mainVideo-haskell" id="subtitle"]] -[[!template text="to jump to any declaration in a file." start="00:05:53.424" video="mainVideo-haskell" id="subtitle"]] -[[!template text="To do that, one has to first run haskell-decl-scan-mode" start="00:05:56.424" video="mainVideo-haskell" id="subtitle"]] -[[!template text="to enter this minor mode." start="00:06:00.664" video="mainVideo-haskell" id="subtitle"]] -[[!template text="Then we can run imenu to go to any definition," start="00:06:03.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="to go to any declaration, like getHomeR." start="00:06:08.144" video="mainVideo-haskell" id="subtitle"]] -[[!template text="Apparently, after running that," start="00:06:11.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="we are able to go to definition." start="00:06:13.824" video="mainVideo-haskell" id="subtitle"]] -[[!template text="So for example, let's see," start="00:06:16.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="we want to find definition of getCityJR." start="00:06:19.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="And indeed, it works" start="00:06:22.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="if it's within the same source file, of course." start="00:06:25.624" video="mainVideo-haskell" id="subtitle"]] -[[!template text="It still does not work for cross-packaging identifiers." start="00:06:28.624" video="mainVideo-haskell" id="subtitle"]] -[[!template text="So HandlerFor is probably an identifier from servant." start="00:06:32.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="Or no, not necessarily servant. Maybe WAI." start="00:06:37.024" video="mainVideo-haskell" id="subtitle"]] -[[!template text="Anyway, it's another library." start="00:06:40.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="And how about find-references?" start="00:06:43.504" video="mainVideo-haskell" id="subtitle"]] -[[!template new="1" text="find-references also works somehow for this file." start="00:06:50.504" video="mainVideo-haskell" id="subtitle"]] -[[!template text="How about WidgetFor?" start="00:07:01.224" video="mainVideo-haskell" id="subtitle"]] -[[!template text="It works for WidgetFor too." start="00:07:06.784" video="mainVideo-haskell" id="subtitle"]] -[[!template text="It has some support for goto-definition and find-references." start="00:07:13.744" video="mainVideo-haskell" id="subtitle"]] -[[!template text="But as usual, it does not support such things cross-package." start="00:07:18.000" video="mainVideo-haskell" id="subtitle"]] -[[!template new="1" text="And finally, we have" start="00:07:26.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="the Sledgehammer HLS Haskell language server." start="00:07:27.365" video="mainVideo-haskell" id="subtitle"]] -[[!template text="It can be used with EGLOT." start="00:07:31.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="But the problem with HLS, HLS has many many features" start="00:07:33.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="because it is a language server," start="00:07:40.904" video="mainVideo-haskell" id="subtitle"]] -[[!template text="like renaming, like eldoc for standard libraries, and so on." start="00:07:42.944" video="mainVideo-haskell" id="subtitle"]] -[[!template text="But the problem with HLS is, one, that it is very, very slow." start="00:07:51.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="And I wouldn't use it with my laptop." start="00:07:57.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="And two, it also does not support cross-package referencing." start="00:08:00.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="In fact, there's an outstanding GitHub issue about this." start="00:08:05.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="So cross-package referencing and goto-definition" start="00:08:08.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="is sort of a common shortfall," start="00:08:13.064" video="mainVideo-haskell" id="subtitle"]] -[[!template text="a common problem for these existing Haskell code explorers." start="00:08:17.264" video="mainVideo-haskell" id="subtitle"]] -[[!template new="1" text="Then finally, we also have hoogle and hackage." start="00:08:21.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="Hoogle is a search engine for Haskell identifiers," start="00:08:23.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="and the results link to Hackage," start="00:08:28.384" video="mainVideo-haskell" id="subtitle"]] -[[!template text="which is the Haskell documentation website" start="00:08:30.744" video="mainVideo-haskell" id="subtitle"]] -[[!template text="for all Haskell libraries." start="00:08:33.704" video="mainVideo-haskell" id="subtitle"]] -[[!template text="Haskell Hackage has functionality" start="00:08:35.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="where you can jump to the source code file rendered in HTML," start="00:08:40.104" video="mainVideo-haskell" id="subtitle"]] -[[!template text="and you can click on the identifiers there" start="00:08:45.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="to jump to definitions," start="00:08:49.544" video="mainVideo-haskell" id="subtitle"]] -[[!template text="but it does not support find references," start="00:08:51.624" video="mainVideo-haskell" id="subtitle"]] -[[!template text="and it is rather basic." start="00:08:54.144" video="mainVideo-haskell" id="subtitle"]] -[[!template new="1" text="Then I learned about haskell-code-explorer," start="00:08:59.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="which is a fully-fledged Haskell code explorer." start="00:09:01.744" video="mainVideo-haskell" id="subtitle"]] -[[!template text="It is written by someone else." start="00:09:05.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="It is a web application" start="00:09:07.824" video="mainVideo-haskell" id="subtitle"]] -[[!template text="for exploring Haskell package codebases." start="00:09:09.264" video="mainVideo-haskell" id="subtitle"]] -[[!template text="The official reference instance for haskell-code-explorer" start="00:09:12.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="is available at this URL, which I will demo soon." start="00:09:16.344" video="mainVideo-haskell" id="subtitle"]] -[[!template text="What I did with these packages... I ported it to GHC 9.2." start="00:09:19.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="I renamed it to hcel because I want to focus on Emacs clients" start="00:09:25.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="rather than JavaScript clients, which I will explain later." start="00:09:29.144" video="mainVideo-haskell" id="subtitle"]] -[[!template text="And I also wrote an Emacs client package, of course." start="00:09:31.000" video="mainVideo-haskell" id="subtitle"]] -[[!template new="1" text="This is what haskell-code-explorer looks like." start="00:09:37.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="On the homepage, it is a list of indexed packages" start="00:09:41.504" video="mainVideo-haskell" id="subtitle"]] -[[!template text="indexed by the indexer." start="00:09:47.024" video="mainVideo-haskell" id="subtitle"]] -[[!template text="One can filter it by the package name" start="00:09:50.144" video="mainVideo-haskell" id="subtitle"]] -[[!template text="or look for identifiers directly across all packages." start="00:09:53.944" video="mainVideo-haskell" id="subtitle"]] -[[!template text="Let's have a look at base. There are three versions." start="00:10:05.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="Let's have a look at the latest version, 4.12.0.0." start="00:10:09.984" video="mainVideo-haskell" id="subtitle"]] -[[!template text="Once entering the package view," start="00:10:15.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="you are shown a list of all modules by their path," start="00:10:19.064" video="mainVideo-haskell" id="subtitle"]] -[[!template text="as well as a tree of these module files." start="00:10:24.544" video="mainVideo-haskell" id="subtitle"]] -[[!template text="You can filter by module name or file name," start="00:10:29.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="or you can search for identifier within the same package" start="00:10:32.624" video="mainVideo-haskell" id="subtitle"]] -[[!template text="or in all packages." start="00:10:34.424" video="mainVideo-haskell" id="subtitle"]] -[[!template text="Let's say we want to learn about Control.Monad." start="00:10:36.000" video="mainVideo-haskell" id="subtitle"]] -[[!template new="1" text="Now we are in the module view." start="00:10:43.304" video="mainVideo-haskell" id="subtitle"]] -[[!template text="The source file is presented to you," start="00:10:46.984" video="mainVideo-haskell" id="subtitle"]] -[[!template text="and it has links to identifiers." start="00:10:49.904" video="mainVideo-haskell" id="subtitle"]] -[[!template text="When you hover over them, the documentation shows up," start="00:10:55.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="including the signature where it is defined." start="00:11:01.904" video="mainVideo-haskell" id="subtitle"]] -[[!template text="You can go to its definition or find references." start="00:11:05.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="Let's say we want to go to the definition of Monad." start="00:11:10.344" video="mainVideo-haskell" id="subtitle"]] -[[!template text="It jumps to the definition site of the monad type class." start="00:11:20.264" video="mainVideo-haskell" id="subtitle"]] -[[!template text="If we click at the definition site," start="00:11:25.584" video="mainVideo-haskell" id="subtitle"]] -[[!template text="it brings up a list of references." start="00:11:28.104" video="mainVideo-haskell" id="subtitle"]] -[[!template text="On the left, you can choose" start="00:11:32.224" video="mainVideo-haskell" id="subtitle"]] -[[!template text="which package you want to find references of monad in." start="00:11:33.744" video="mainVideo-haskell" id="subtitle"]] -[[!template text="Let's look at the random one, avwx." start="00:11:39.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="Here is a list of results where Monad is used in avwx." start="00:11:47.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="This is a module path." start="00:11:54.144" video="mainVideo-haskell" id="subtitle"]] -[[!template text="One can go to any of these results." start="00:11:57.864" video="mainVideo-haskell" id="subtitle"]] -[[!template text="We can search for things in all packages" start="00:12:06.424" video="mainVideo-haskell" id="subtitle"]] -[[!template text="or in the current package." start="00:12:07.944" video="mainVideo-haskell" id="subtitle"]] -[[!template text="Let’s say I want to search for "Read"" start="00:12:09.584" video="mainVideo-haskell" id="subtitle"]] -[[!template text="I think this is the "Read" that is commonly used in Haskell," start="00:12:13.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="the read type class for parsing strings into values." start="00:12:19.344" video="mainVideo-haskell" id="subtitle"]] -[[!template text="I think that is more or less it." start="00:12:25.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="That is the Haskell Code Explorer web application" start="00:12:31.104" video="mainVideo-haskell" id="subtitle"]] -[[!template text="in all its glory." start="00:12:34.624" video="mainVideo-haskell" id="subtitle"]] -[[!template new="1" text="Let's go back to the slides." start="00:12:38.304" video="mainVideo-haskell" id="subtitle"]] -[[!template text="That was the web application," start="00:12:40.984" video="mainVideo-haskell" id="subtitle"]] -[[!template text="which is basically a JavaScript client" start="00:12:43.464" video="mainVideo-haskell" id="subtitle"]] -[[!template text="that talks to the server" start="00:12:46.544" video="mainVideo-haskell" id="subtitle"]] -[[!template text="by sending requests and receiving" start="00:12:48.744" video="mainVideo-haskell" id="subtitle"]] -[[!template text="and parsing the JSON results or JSON responses." start="00:12:51.064" video="mainVideo-haskell" id="subtitle"]] -[[!template text="Initially, I was interested in hacking the web client." start="00:12:55.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="It uses the ember.js web framework." start="00:13:02.504" video="mainVideo-haskell" id="subtitle"]] -[[!template text="The first thing to do was to npm install ember-cli." start="00:13:05.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="It gives me 12 vulnerabilities," start="00:13:09.944" video="mainVideo-haskell" id="subtitle"]] -[[!template text="4 low, 2 moderate, 3 high, 3 critical." start="00:13:16.224" video="mainVideo-haskell" id="subtitle"]] -[[!template text="I don't know how often it is the case" start="00:13:19.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="when we don't really care about these nasty vulnerabilities" start="00:13:26.184" video="mainVideo-haskell" id="subtitle"]] -[[!template text="from Node.js or npm because they are so common." start="00:13:33.064" video="mainVideo-haskell" id="subtitle"]] -[[!template text="I don't quite like that." start="00:13:36.000" video="mainVideo-haskell" id="subtitle"]] -[[!template new="1" text="Another reason for favoring Emacs clients" start="00:13:41.144" video="mainVideo-haskell" id="subtitle"]] -[[!template text="over JavaScript clients is user freedom." start="00:13:45.464" video="mainVideo-haskell" id="subtitle"]] -[[!template text="Emacs is geared towards user freedom." start="00:13:49.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="It allows users maximum freedom to customize or mod Emacs." start="00:13:53.384" video="mainVideo-haskell" id="subtitle"]] -[[!template text="I think Emacs clients can be a way to fix JavaScript traps," start="00:14:01.664" video="mainVideo-haskell" id="subtitle"]] -[[!template text="like using user scripts to replace non-free JavaScript." start="00:14:07.264" video="mainVideo-haskell" id="subtitle"]] -[[!template text="There are tools to do that, for example, like Haketilo." start="00:14:14.344" video="mainVideo-haskell" id="subtitle"]] -[[!template text="Why write JavaScript replacement" start="00:14:19.584" video="mainVideo-haskell" id="subtitle"]] -[[!template text="if we can write Elisp replacement?" start="00:14:21.504" video="mainVideo-haskell" id="subtitle"]] -[[!template text="If we overwrite all kinds of front-ends in Emacs" start="00:14:25.264" video="mainVideo-haskell" id="subtitle"]] -[[!template text="for commonly-used web applications" start="00:14:31.784" video="mainVideo-haskell" id="subtitle"]] -[[!template text="like Reddit, Hacker News, what have you," start="00:14:34.504" video="mainVideo-haskell" id="subtitle"]] -[[!template text="then we have an Emacs app store" start="00:14:37.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="where we can just install these applications" start="00:14:40.904" video="mainVideo-haskell" id="subtitle"]] -[[!template text="and browse the web more freely." start="00:14:43.704" video="mainVideo-haskell" id="subtitle"]] -[[!template new="1" text="Back to hcel, which is the Emacs client I wrote." start="00:14:51.184" video="mainVideo-haskell" id="subtitle"]] -[[!template text="I tried to reuse as much of Emacs built-ins as possible," start="00:14:56.144" video="mainVideo-haskell" id="subtitle"]] -[[!template text="including eldoc, for showing documentation," start="00:14:59.184" video="mainVideo-haskell" id="subtitle"]] -[[!template text="xref for cross-referencer," start="00:15:03.144" video="mainVideo-haskell" id="subtitle"]] -[[!template text="compilation-mode for showing search results of identifiers," start="00:15:04.864" video="mainVideo-haskell" id="subtitle"]] -[[!template text="outline-mode for a hierarchical view" start="00:15:07.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="of package module identifiers," start="00:15:11.704" video="mainVideo-haskell" id="subtitle"]] -[[!template text="sort of a cursor-mode for highlighting identifiers," start="00:15:14.384" video="mainVideo-haskell" id="subtitle"]] -[[!template text="help-mode for displaying quick help for Haskell identifiers," start="00:15:18.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="integration with haddorg," start="00:15:26.144" video="mainVideo-haskell" id="subtitle"]] -[[!template text="which I will mention later, etc." start="00:15:27.704" video="mainVideo-haskell" id="subtitle"]] -[[!template text="It is available as hcel without the dot on GNU ELPA." start="00:15:31.304" video="mainVideo-haskell" id="subtitle"]] -[[!template text="Time for a demo." start="00:15:38.000" video="mainVideo-haskell" id="subtitle"]] -[[!template new="1" text="To start using hc.el, surprise surprise," start="00:15:40.184" video="mainVideo-haskell" id="subtitle"]] -[[!template text="we run the hcel command." start="00:15:42.584" video="mainVideo-haskell" id="subtitle"]] -[[!template text="We are presented with a list of packages" start="00:15:45.184" video="mainVideo-haskell" id="subtitle"]] -[[!template text="indexed by the hcel indexer." start="00:15:46.984" video="mainVideo-haskell" id="subtitle"]] -[[!template text="This is an outline mode," start="00:15:52.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="so we can tab to list all the modules" start="00:15:54.064" video="mainVideo-haskell" id="subtitle"]] -[[!template text="represented by the module path." start="00:15:58.824" video="mainVideo-haskell" id="subtitle"]] -[[!template text="We can further tab into the list of identifiers" start="00:16:01.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="declared in this module." start="00:16:03.504" video="mainVideo-haskell" id="subtitle"]] -[[!template text="Now it asks whether you want to open module source." start="00:16:05.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="This is because some module source code" start="00:16:09.184" video="mainVideo-haskell" id="subtitle"]] -[[!template text="can be quite large and it can take a bit of time." start="00:16:11.984" video="mainVideo-haskell" id="subtitle"]] -[[!template text="In this case, the control monad is quite small," start="00:16:14.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="so let's say yes." start="00:16:17.784" video="mainVideo-haskell" id="subtitle"]] -[[!template text="We see the list of identifiers." start="00:16:19.944" video="mainVideo-haskell" id="subtitle"]] -[[!template text="One can jump to an identifier forever." start="00:16:24.104" video="mainVideo-haskell" id="subtitle"]] -[[!template text="As you can see, the identifiers at points are highlighted." start="00:16:28.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="This can be particularly useful" start="00:16:33.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="in a large function declaration" start="00:16:36.224" video="mainVideo-haskell" id="subtitle"]] -[[!template text="where you come to see, for example," start="00:16:38.704" video="mainVideo-haskell" id="subtitle"]] -[[!template text="all the occurrences of an identifier" start="00:16:40.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="inside the body of the declaration." start="00:16:44.304" video="mainVideo-haskell" id="subtitle"]] -[[!template new="1" text="These are declarations" start="00:16:48.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="which in Haskell mode are listed in imenu." start="00:16:50.824" video="mainVideo-haskell" id="subtitle"]] -[[!template text="We can do the same here in hcel source mode." start="00:16:53.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="It lists all the declarations with their signature." start="00:17:00.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="Let's say we want to jump to this funny operator." start="00:17:06.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="It worked and you can also go back and forth" start="00:17:13.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="within the declarations by pressing "n" and "p"." start="00:17:20.424" video="mainVideo-haskell" id="subtitle"]] -[[!template text="Similarly, you can do something similar in the outline mode" start="00:17:26.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="by toggling the follow mode, just like in org-agenda." start="00:17:30.904" video="mainVideo-haskell" id="subtitle"]] -[[!template text="Let's turn it off." start="00:17:38.000" video="mainVideo-haskell" id="subtitle"]] -[[!template new="1" text="Now, how about find definition references?" start="00:17:40.224" video="mainVideo-haskell" id="subtitle"]] -[[!template text="Using xref," start="00:17:46.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="we can jump to the definition of Int and jump back." start="00:17:49.064" video="mainVideo-haskell" id="subtitle"]] -[[!template text="Jump to Maybe, jump back." start="00:17:53.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="Let's have a look at references of replicateM." start="00:17:56.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="There are plenty of them." start="00:18:01.024" video="mainVideo-haskell" id="subtitle"]] -[[!template text="Maybe we want to check out ghc-lib." start="00:18:03.464" video="mainVideo-haskell" id="subtitle"]] -[[!template text="Here are all the references" start="00:18:09.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="and you can of course jump to any of them in the results." start="00:18:11.344" video="mainVideo-haskell" id="subtitle"]] -[[!template text="Cool." start="00:18:16.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="You may have already noticed" start="00:18:19.000" video="mainVideo-haskell" id="subtitle"]] -[[!template new="1" text="the eldoc displaying the documentation" start="00:18:21.864" video="mainVideo-haskell" id="subtitle"]] -[[!template text="and signature of identifiers." start="00:18:27.184" video="mainVideo-haskell" id="subtitle"]] -[[!template text="For example, here it shows the signature of replicateM," start="00:18:34.904" video="mainVideo-haskell" id="subtitle"]] -[[!template text="where it is defined, and its documentation." start="00:18:44.104" video="mainVideo-haskell" id="subtitle"]] -[[!template text="We can bring up the eldoc buffer." start="00:18:47.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="In the eldoc buffer," start="00:18:56.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="there are also links to other identifiers," start="00:18:58.264" video="mainVideo-haskell" id="subtitle"]] -[[!template text="which takes you to the definition of these identifiers," start="00:19:00.184" video="mainVideo-haskell" id="subtitle"]] -[[!template text="like minBound." start="00:19:04.544" video="mainVideo-haskell" id="subtitle"]] -[[!template text="Apparently, this is not working." start="00:19:07.624" video="mainVideo-haskell" id="subtitle"]] -[[!template text="I'm pretty sure it maybe works." start="00:19:10.864" video="mainVideo-haskell" id="subtitle"]] -[[!template text="Let's go to nothing or just..." start="00:19:13.104" video="mainVideo-haskell" id="subtitle"]] -[[!template text="I think those didn't work because" start="00:19:17.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="the module source for those identifiers is not open." start="00:19:19.864" video="mainVideo-haskell" id="subtitle"]] -[[!template new="1" text="Of course, you can search" start="00:19:24.144" video="mainVideo-haskell" id="subtitle"]] -[[!template text="for any identifiers across all indexed packages" start="00:19:30.304" video="mainVideo-haskell" id="subtitle"]] -[[!template text="by invoking hcel-global-ids." start="00:19:33.024" video="mainVideo-haskell" id="subtitle"]] -[[!template text="Let's say we want to search for Read." start="00:19:38.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="We are presented with a list of results," start="00:19:42.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="which are identifiers starting with Read with capital R." start="00:19:47.464" video="mainVideo-haskell" id="subtitle"]] -[[!template text="They also show where they are defined" start="00:19:54.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="and the documentation, just like in eldoc." start="00:19:57.304" video="mainVideo-haskell" id="subtitle"]] -[[!template text="One can also directly jump to the identifier" start="00:20:07.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="in the mini-buffer results." start="00:20:13.944" video="mainVideo-haskell" id="subtitle"]] -[[!template text="For example, we want to check out this Read2" start="00:20:20.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="defined in base-4.12.0.0 Data.Functor.Classes" start="00:20:22.024" video="mainVideo-haskell" id="subtitle"]] -[[!template text="There we go." start="00:20:28.000" video="mainVideo-haskell" id="subtitle"]] -[[!template new="1" text="Another functionality of hcel" start="00:20:34.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="is the help buffer integration." start="00:20:37.864" video="mainVideo-haskell" id="subtitle"]] -[[!template text="We can do hcel-help and then let's say" start="00:20:41.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="we want to learn about the read type class." start="00:20:46.565" video="mainVideo-haskell" id="subtitle"]] -[[!template text="This is a help buffer" start="00:20:52.744" video="mainVideo-haskell" id="subtitle"]] -[[!template text="and you can jump to other definitions" start="00:20:55.184" video="mainVideo-haskell" id="subtitle"]] -[[!template text="within the help buffer" start="00:21:00.904" video="mainVideo-haskell" id="subtitle"]] -[[!template text="to read the documentation like readsPrec." start="00:21:02.464" video="mainVideo-haskell" id="subtitle"]] -[[!template text="It says Server version cannot be satistifed. Actual version." start="00:21:07.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="This means we need to tell hecl" start="00:21:11.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="that the server has the correct version." start="00:21:14.784" video="mainVideo-haskell" id="subtitle"]] -[[!template text="hecl-fetch-server-version." start="00:21:17.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="Wait a bit for it to update" start="00:21:21.744" video="mainVideo-haskell" id="subtitle"]] -[[!template text="the knowledge of the server version." start="00:21:25.704" video="mainVideo-haskell" id="subtitle"]] -[[!template text="Now you can follow the links, Read, readsPrec." start="00:21:27.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="You can do the "l" and "r" to navigate within the history." start="00:21:33.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="ReadS, ReadP." start="00:21:38.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="Just like in the help buffer for elisp code," start="00:21:43.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="you can jump to the definition." start="00:21:46.024" video="mainVideo-haskell" id="subtitle"]] -[[!template text="I believe that is everything, more or less." start="00:21:53.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="That concludes the demo." start="00:22:00.000" video="mainVideo-haskell" id="subtitle"]] -[[!template new="1" text="Now let's turn to haddorg," start="00:22:05.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="which is an Org backend for Haddock." start="00:22:07.144" video="mainVideo-haskell" id="subtitle"]] -[[!template text="Haddock is the documentation generator for Haskell packages." start="00:22:09.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="For example," start="00:22:13.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="the official Haskell package documentation website Hackage," start="00:22:15.144" video="mainVideo-haskell" id="subtitle"]] -[[!template text="all the documentation there is generated by Haddock" start="00:22:22.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="into the HTML format." start="00:22:25.904" video="mainVideo-haskell" id="subtitle"]] -[[!template text="Haddock has several backends" start="00:22:28.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="that convert the intermediate representation" start="00:22:31.424" video="mainVideo-haskell" id="subtitle"]] -[[!template text="called interface to various output formats," start="00:22:34.384" video="mainVideo-haskell" id="subtitle"]] -[[!template text="including HTML, LaTeX, and Hugo." start="00:22:37.064" video="mainVideo-haskell" id="subtitle"]] -[[!template text="HTML is the main format with a lot of features." start="00:22:41.864" video="mainVideo-haskell" id="subtitle"]] -[[!template text="LaTeX is less so, and I don't think it is widely used." start="00:22:44.904" video="mainVideo-haskell" id="subtitle"]] -[[!template text="Let's have a look at an HTML example." start="00:22:49.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="This is a PDF because these HTML files can be rather large" start="00:22:53.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="and slow down EWW significantly." start="00:23:01.184" video="mainVideo-haskell" id="subtitle"]] -[[!template text="It's faster to convert it to PDF" start="00:23:07.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="and read it from pdf-tools." start="00:23:10.264" video="mainVideo-haskell" id="subtitle"]] -[[!template text="Looks like this is as big as it goes." start="00:23:17.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="I hope you can still see it." start="00:23:20.864" video="mainVideo-haskell" id="subtitle"]] -[[!template text="Can I still enlarge it a bit more? Maybe." start="00:23:26.144" video="mainVideo-haskell" id="subtitle"]] -[[!template new="1" text="This is Servant.Server." start="00:23:30.144" video="mainVideo-haskell" id="subtitle"]] -[[!template text="It is a module in the servant-server package." start="00:23:33.064" video="mainVideo-haskell" id="subtitle"]] -[[!template text="It is a widely used package for writing servers." start="00:23:36.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="It starts with a heading, which is the name of the module," start="00:23:42.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="and the table of contents." start="00:23:49.904" video="mainVideo-haskell" id="subtitle"]] -[[!template text="Then a heading: Run an wai application from an API." start="00:23:52.784" video="mainVideo-haskell" id="subtitle"]] -[[!template text="Under this heading, there are all the relevant identifiers" start="00:23:56.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="that is concerned with running a WAI application from API," start="00:24:00.904" video="mainVideo-haskell" id="subtitle"]] -[[!template text="including serve, which is one of the main entry points" start="00:24:08.624" video="mainVideo-haskell" id="subtitle"]] -[[!template text="for a Servant.Server." start="00:24:13.304" video="mainVideo-haskell" id="subtitle"]] -[[!template text="It has a signature linkable to the other identifiers," start="00:24:15.624" video="mainVideo-haskell" id="subtitle"]] -[[!template text="the documentation," start="00:24:21.704" video="mainVideo-haskell" id="subtitle"]] -[[!template text="an example with a Haskell source code block." start="00:24:23.104" video="mainVideo-haskell" id="subtitle"]] -[[!template text="That's what HTML output looks like." start="00:24:26.744" video="mainVideo-haskell" id="subtitle"]] -[[!template new="1" text="As I mentioned," start="00:24:31.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="there are several downsides or drawbacks with that," start="00:24:34.024" video="mainVideo-haskell" id="subtitle"]] -[[!template text="like the HTML files can be huge and slow down EWW." start="00:24:35.904" video="mainVideo-haskell" id="subtitle"]] -[[!template text="Also, every module is an HTML of itself," start="00:24:41.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="and there's also an HTML for the package" start="00:24:46.224" video="mainVideo-haskell" id="subtitle"]] -[[!template text="with a list of all the modules." start="00:24:48.384" video="mainVideo-haskell" id="subtitle"]] -[[!template text="Whereas the Org backend" start="00:24:50.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="is better in that it is much more compact." start="00:24:54.744" video="mainVideo-haskell" id="subtitle"]] -[[!template text="All the modules under the same package" start="00:25:04.264" video="mainVideo-haskell" id="subtitle"]] -[[!template text="are included in one Org file" start="00:25:07.504" video="mainVideo-haskell" id="subtitle"]] -[[!template text="as sub-headings, level 2 headings." start="00:25:10.784" video="mainVideo-haskell" id="subtitle"]] -[[!template text="So, servant-server, Servant.Server, that is the module." start="00:25:13.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="So basically, this level 2 heading" start="00:25:19.504" video="mainVideo-haskell" id="subtitle"]] -[[!template text="contains all the information in this PDF." start="00:25:21.944" video="mainVideo-haskell" id="subtitle"]] -[[!template text="Run the WAI application from API, serve." start="00:25:25.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="It has a signature that links to other identifiers" start="00:25:29.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="and the documentation that's also linkable." start="00:25:39.224" video="mainVideo-haskell" id="subtitle"]] -[[!template text="The Haskell source block is now an Org source block," start="00:25:42.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="and you can do all sorts of interesting things" start="00:25:47.224" video="mainVideo-haskell" id="subtitle"]] -[[!template text="with it using org-babel." start="00:25:49.504" video="mainVideo-haskell" id="subtitle"]] -[[!template new="1" text="Let's check the links as server." start="00:25:52.744" video="mainVideo-haskell" id="subtitle"]] -[[!template text="Right, so the link works." start="00:25:56.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="Application, right, Request." start="00:26:00.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="It also supports cross-packaging package linking," start="00:26:05.384" video="mainVideo-haskell" id="subtitle"]] -[[!template text="so following the link to request" start="00:26:08.384" video="mainVideo-haskell" id="subtitle"]] -[[!template text="takes us from servant-server package Org documentation" start="00:26:12.304" video="mainVideo-haskell" id="subtitle"]] -[[!template text="to the WAI Org documentation." start="00:26:17.624" video="mainVideo-haskell" id="subtitle"]] -[[!template new="1" text="Another nice thing with Org documentation" start="00:26:24.784" video="mainVideo-haskell" id="subtitle"]] -[[!template text="is that you can use Org functions" start="00:26:27.544" video="mainVideo-haskell" id="subtitle"]] -[[!template text="like org-goto to jump to any identifiers." start="00:26:32.744" video="mainVideo-haskell" id="subtitle"]] -[[!template text="Let's say we want to jump to application." start="00:26:40.544" video="mainVideo-haskell" id="subtitle"]] -[[!template text="We have toApplication. So it jumpts to toApplication." start="00:26:45.904" video="mainVideo-haskell" id="subtitle"]] -[[!template text="I guess application is not an identifier," start="00:26:50.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="yes, it is more like a type alias," start="00:26:54.024" video="mainVideo-haskell" id="subtitle"]] -[[!template text="that's why we couldn't find it." start="00:26:55.824" video="mainVideo-haskell" id="subtitle"]] -[[!template text="So that is haddorg." start="00:26:58.664" video="mainVideo-haskell" id="subtitle"]] -[[!template text="And of course, I implemented a bit of integration" start="00:27:01.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="between haddorg and hcel" start="00:27:06.104" video="mainVideo-haskell" id="subtitle"]] -[[!template text="so that we can jump from one to the other." start="00:27:08.544" video="mainVideo-haskell" id="subtitle"]] -[[!template text="Let's go back to servant." start="00:27:11.304" video="mainVideo-haskell" id="subtitle"]] -[[!template text="Let's see, ServerT." start="00:27:15.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="Maybe we want to check out" start="00:27:24.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="the source code definition of ServerT." start="00:27:27.104" video="mainVideo-haskell" id="subtitle"]] -[[!template text="To find out exactly what sort of type alias it is," start="00:27:31.944" video="mainVideo-haskell" id="subtitle"]] -[[!template text="like what is the alias (or type synonym)" start="00:27:36.264" video="mainVideo-haskell" id="subtitle"]] -[[!template text="We run hcel-identifier-at-point--" start="00:27:43.184" video="mainVideo-haskell" id="subtitle"]] -[[!template text="sorry, hcel-haddorg-to-hcel-definition..." start="00:27:49.504" video="mainVideo-haskell" id="subtitle"]] -[[!template text="Oh, we have an HTTP error." start="00:27:52.344" video="mainVideo-haskell" id="subtitle"]] -[[!template text="Typ ServerT not found in module src/Servant/Server.hs" start="00:27:55.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="Why? Well, this is because" start="00:27:59.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="the HCEL server only understands," start="00:28:01.125" video="mainVideo-haskell" id="subtitle"]] -[[!template text="it only has knowledge of identifiers" start="00:28:04.944" video="mainVideo-haskell" id="subtitle"]] -[[!template text="that is defined in the original source file." start="00:28:07.824" video="mainVideo-haskell" id="subtitle"]] -[[!template text="So, it is not aware of, say," start="00:28:12.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="identifiers that are re-exported in the module." start="00:28:17.184" video="mainVideo-haskell" id="subtitle"]] -[[!template text="Most likely, Servant.Server module re-exports ServerT" start="00:28:21.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="from another module." start="00:28:25.824" video="mainVideo-haskell" id="subtitle"]] -[[!template text="We will probably have better luck" start="00:28:28.704" video="mainVideo-haskell" id="subtitle"]] -[[!template text="looking into some internal modules like this one." start="00:28:29.744" video="mainVideo-haskell" id="subtitle"]] -[[!template text="Let's try this type class HasContextEntry." start="00:28:35.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="So this time it worked." start="00:28:39.000" video="mainVideo-haskell" id="subtitle"]] -[[!template new="1" text="And, of course, we can go the other direction" start="00:28:42.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="from hecl to haddorg." start="00:28:44.344" video="mainVideo-haskell" id="subtitle"]] -[[!template text="Let's say if we want to display named context" start="00:28:48.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="in the haddorg documentation" start="00:28:51.584" video="mainVideo-haskell" id="subtitle"]] -[[!template text="so that we can read about, other identifiers documentation" start="00:28:54.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="that is related to named context." start="00:29:01.624" video="mainVideo-haskell" id="subtitle"]] -[[!template text="We do hecl-identifier-at-point-to-haddorg" start="00:29:04.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="And it does take us to the server-server old file." start="00:29:08.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="Okay." start="00:29:14.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="And that concludes my presentation." start="00:29:18.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="You can find hecl in GNU Elpa," start="00:29:21.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="and you can also find the source code," start="00:29:23.584" video="mainVideo-haskell" id="subtitle"]] -[[!template text="as well as the source of haddorg" start="00:29:25.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="and instructions on how to generate org documentation" start="00:29:27.464" video="mainVideo-haskell" id="subtitle"]] -[[!template text="using haddorg in my cgit instance." start="00:29:29.864" video="mainVideo-haskell" id="subtitle"]] -[[!template text="Thank you for your attention." start="00:29:33.000" video="mainVideo-haskell" id="subtitle"]] -[[!template text="I hope you enjoy the rest of the conference." start="00:29:36.784" video="mainVideo-haskell" id="subtitle"]] -[[!template text="Thank you." start="00:29:38.000" video="mainVideo-haskell" id="subtitle"]] +[[!template new="1" text="""Today, I will talk about Haskell code exploration for Emacs.""" start="00:00:00.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""What is Haskell? It is a purely functional language.""" start="00:00:03.500" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""For example, every value in Haskell is immutable.""" start="00:00:06.500" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""And it is the main compiler of Haskell, GHC.""" start="00:00:09.500" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""It provides API for the whole compilation pipeline.""" start="00:00:13.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""For example, the tools mentioned in this talk,""" start="00:00:16.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""including hcel and haddorg,""" start="00:00:18.424" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""they use, they heavily utilize the GHC front-end API""" start="00:00:20.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""for parsing and understanding""" start="00:00:24.500" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""the identifiers in Haskell source files.""" start="00:00:26.744" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""Roughly speaking,""" start="00:00:29.500" video="mainVideo-haskell" id="subtitle"]] +[[!template new="1" text="""a Haskell program consists of several parts.""" start="00:00:31.544" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""it begins with some front matters, including,""" start="00:00:34.664" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""for example, language extensions,""" start="00:00:37.064" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""which are optional language features one might want to use""" start="00:00:40.024" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""for convenience.""" start="00:00:44.064" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""The front matters also contain module exports.""" start="00:00:48.464" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""So for example, here we define,""" start="00:00:52.500" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""we declare module F2Md.Config""" start="00:00:55.784" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""for this Haskell source file,""" start="00:00:58.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""which exports these four identifiers""" start="00:01:00.984" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""that other source files can use when importing F2Md.Config.""" start="00:01:03.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""And the next will be""" start="00:01:07.500" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""a block of imports so that we can use libraries""" start="00:01:10.784" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""and identifiers in these libraries.""" start="00:01:14.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""The bulk of a Haskell source file normally is""" start="00:01:17.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""a list of declarations,""" start="00:01:21.744" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""including values, types, and instances, and so on.""" start="00:01:23.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""The difference between a value and a type is that""" start="00:01:26.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""the type of a value is a type,""" start="00:01:29.184" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""and the type of a type is a kind.""" start="00:01:30.500" video="mainVideo-haskell" id="subtitle"]] +[[!template new="1" text="""For example, here's a small block of Haskell source code.""" start="00:01:34.064" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""We define Range type""" start="00:01:38.584" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""from a lower-end integer to a higher-end integer.""" start="00:01:41.504" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""We also declare a value r of the type Range,""" start="00:01:45.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""which is Range from 2 to 7,""" start="00:01:51.464" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""because in Haskell, we like to--""" start="00:01:54.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""by default, functions can be curried,""" start="00:02:01.104" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""which basically means, by default, we want to utilize""" start="00:02:04.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""the partial application of functions.""" start="00:02:09.904" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""We don't require parens surrounding arguments""" start="00:02:12.000" video="mainVideo-haskell" id="subtitle"]] +[[!template new="1" text="""when invoking a function.""" start="00:02:17.384" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""That makes it possible, if you want,""" start="00:02:19.464" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""to write Haskell like Lisp""" start="00:02:22.725" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""by adding a bit of redundant parens.""" start="00:02:25.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""So for example,""" start="00:02:28.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""here are two blocks of code, one Lisp, one Haskell,""" start="00:02:30.144" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""and they look quite similar to each other.""" start="00:02:33.784" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""What is a code explorer?""" start="00:02:36.000" video="mainVideo-haskell" id="subtitle"]] +[[!template new="1" text="""A code explorer is a tool""" start="00:02:38.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""to browse its code base to its code comprehension.""" start="00:02:39.544" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""Code explorer commonly comes with""" start="00:02:42.724" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""several functionalities or features,""" start="00:02:45.424" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""including a cross-referencer,""" start="00:02:47.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""which allows going to definitions of an identifier at points""" start="00:02:49.344" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""or looking up references of an identifier,""" start="00:02:53.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""like where it is used.""" start="00:02:56.544" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""So the example in Emacs would be xref.""" start="00:02:58.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""Code explorer also would be able to show you""" start="00:03:04.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""documentation and signatures of identifiers at points.""" start="00:03:07.704" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""In Emacs, that would be eldoc.""" start="00:03:10.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""It also commonly allows you to search for identifiers.""" start="00:03:13.984" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""Something like that in Emacs""" start="00:03:17.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""could be describe-function and find-function.""" start="00:03:19.984" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""Code explorer is normally""" start="00:03:22.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""quite often implemented in two parts,""" start="00:03:24.784" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""the indexer and the server,""" start="00:03:27.464" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""where the indexer parses the source code files,""" start="00:03:28.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""indexes the identifiers,""" start="00:03:32.584" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""and stores the information of identifiers""" start="00:03:34.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""like the definition, size, and the currencies,""" start="00:03:36.384" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""either in databases or in files.""" start="00:03:38.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""The other part is the server,""" start="00:03:42.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""which uses the database created by the indexer""" start="00:03:44.544" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""to serve the information of the identifier.""" start="00:03:49.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""Before I present my solution to code exploring,""" start="00:03:53.104" video="mainVideo-haskell" id="subtitle"]] +[[!template new="1" text="""some description of prior art is in order.""" start="00:03:57.104" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""There are several tools that you can use""" start="00:04:01.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""to aid code exploration,""" start="00:04:05.384" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""including tech-based tools like hasktags and hs-tags.""" start="00:04:08.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""The limitation with these tools""" start="00:04:13.544" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""is they are focused on the current projects only""" start="00:04:15.584" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""and do not work""" start="00:04:18.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""for cross-packaging reference and definition.""" start="00:04:19.704" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""Another problem with the tag-based tools is""" start="00:04:26.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""they might not handle symbols with the same name properly.""" start="00:04:31.045" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""Sometimes they get confused,""" start="00:04:34.784" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""and they ask you to choose which definition,""" start="00:04:36.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""what is the correct definition site,""" start="00:04:43.424" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""even though the occurrence of the symbol""" start="00:04:46.024" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""or the symbol at point has only one definition ambiguously.""" start="00:04:49.344" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""Another tool is the haskell-mode.""" start="00:04:55.000" video="mainVideo-haskell" id="subtitle"]] +[[!template new="1" text="""It has some limited support for eldoc""" start="00:04:58.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""by displaying the signature of an identifier at points,""" start="00:05:02.784" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""but the identifier has to be something""" start="00:05:06.704" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""that is commonly known or sort of built-in""" start="00:05:11.864" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""or come from the base library of Haskell.""" start="00:05:15.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""So for example,""" start="00:05:18.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""it works for common functions like head and tail.""" start="00:05:20.344" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""And you can see that the signature is displayed here.""" start="00:05:24.344" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""However, it does not work for,""" start="00:05:27.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""let's say, IO. IO is a type.""" start="00:05:29.664" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""Maybe that's the reason.""" start="00:05:31.904" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""Let's find another function""" start="00:05:33.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""that's not from the base library.""" start="00:05:37.424" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""toJSON is from the Aeson library,""" start="00:05:40.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""so no signature is displayed here.""" start="00:05:42.000" video="mainVideo-haskell" id="subtitle"]] +[[!template new="1" text="""It also provides""" start="00:05:47.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""some sort of goto-declaration functionality""" start="00:05:51.264" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""to jump to any declaration in a file.""" start="00:05:53.424" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""To do that, one has to first run haskell-decl-scan-mode""" start="00:05:56.424" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""to enter this minor mode.""" start="00:06:00.664" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""Then we can run imenu to go to any definition,""" start="00:06:03.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""to go to any declaration, like getHomeR.""" start="00:06:08.144" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""Apparently, after running that,""" start="00:06:11.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""we are able to go to definition.""" start="00:06:13.824" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""So for example, let's see,""" start="00:06:16.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""we want to find definition of getCityJR.""" start="00:06:19.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""And indeed, it works""" start="00:06:22.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""if it's within the same source file, of course.""" start="00:06:25.624" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""It still does not work for cross-packaging identifiers.""" start="00:06:28.624" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""So HandlerFor is probably an identifier from servant.""" start="00:06:32.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""Or no, not necessarily servant. Maybe WAI.""" start="00:06:37.024" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""Anyway, it's another library.""" start="00:06:40.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""And how about find-references?""" start="00:06:43.504" video="mainVideo-haskell" id="subtitle"]] +[[!template new="1" text="""find-references also works somehow for this file.""" start="00:06:50.504" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""How about WidgetFor?""" start="00:07:01.224" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""It works for WidgetFor too.""" start="00:07:06.784" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""It has some support for goto-definition and find-references.""" start="00:07:13.744" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""But as usual, it does not support such things cross-package.""" start="00:07:18.000" video="mainVideo-haskell" id="subtitle"]] +[[!template new="1" text="""And finally, we have""" start="00:07:26.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""the Sledgehammer HLS Haskell language server.""" start="00:07:27.365" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""It can be used with EGLOT.""" start="00:07:31.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""But the problem with HLS, HLS has many many features""" start="00:07:33.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""because it is a language server,""" start="00:07:40.904" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""like renaming, like eldoc for standard libraries, and so on.""" start="00:07:42.944" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""But the problem with HLS is, one, that it is very, very slow.""" start="00:07:51.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""And I wouldn't use it with my laptop.""" start="00:07:57.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""And two, it also does not support cross-package referencing.""" start="00:08:00.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""In fact, there's an outstanding GitHub issue about this.""" start="00:08:05.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""So cross-package referencing and goto-definition""" start="00:08:08.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""is sort of a common shortfall,""" start="00:08:13.064" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""a common problem for these existing Haskell code explorers.""" start="00:08:17.264" video="mainVideo-haskell" id="subtitle"]] +[[!template new="1" text="""Then finally, we also have hoogle and hackage.""" start="00:08:21.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""Hoogle is a search engine for Haskell identifiers,""" start="00:08:23.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""and the results link to Hackage,""" start="00:08:28.384" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""which is the Haskell documentation website""" start="00:08:30.744" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""for all Haskell libraries.""" start="00:08:33.704" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""Haskell Hackage has functionality""" start="00:08:35.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""where you can jump to the source code file rendered in HTML,""" start="00:08:40.104" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""and you can click on the identifiers there""" start="00:08:45.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""to jump to definitions,""" start="00:08:49.544" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""but it does not support find references,""" start="00:08:51.624" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""and it is rather basic.""" start="00:08:54.144" video="mainVideo-haskell" id="subtitle"]] +[[!template new="1" text="""Then I learned about haskell-code-explorer,""" start="00:08:59.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""which is a fully-fledged Haskell code explorer.""" start="00:09:01.744" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""It is written by someone else.""" start="00:09:05.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""It is a web application""" start="00:09:07.824" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""for exploring Haskell package codebases.""" start="00:09:09.264" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""The official reference instance for haskell-code-explorer""" start="00:09:12.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""is available at this URL, which I will demo soon.""" start="00:09:16.344" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""What I did with these packages... I ported it to GHC 9.2.""" start="00:09:19.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""I renamed it to hcel because I want to focus on Emacs clients""" start="00:09:25.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""rather than JavaScript clients, which I will explain later.""" start="00:09:29.144" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""And I also wrote an Emacs client package, of course.""" start="00:09:31.000" video="mainVideo-haskell" id="subtitle"]] +[[!template new="1" text="""This is what haskell-code-explorer looks like.""" start="00:09:37.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""On the homepage, it is a list of indexed packages""" start="00:09:41.504" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""indexed by the indexer.""" start="00:09:47.024" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""One can filter it by the package name""" start="00:09:50.144" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""or look for identifiers directly across all packages.""" start="00:09:53.944" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""Let's have a look at base. There are three versions.""" start="00:10:05.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""Let's have a look at the latest version, 4.12.0.0.""" start="00:10:09.984" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""Once entering the package view,""" start="00:10:15.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""you are shown a list of all modules by their path,""" start="00:10:19.064" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""as well as a tree of these module files.""" start="00:10:24.544" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""You can filter by module name or file name,""" start="00:10:29.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""or you can search for identifier within the same package""" start="00:10:32.624" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""or in all packages.""" start="00:10:34.424" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""Let's say we want to learn about Control.Monad.""" start="00:10:36.000" video="mainVideo-haskell" id="subtitle"]] +[[!template new="1" text="""Now we are in the module view.""" start="00:10:43.304" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""The source file is presented to you,""" start="00:10:46.984" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""and it has links to identifiers.""" start="00:10:49.904" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""When you hover over them, the documentation shows up,""" start="00:10:55.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""including the signature where it is defined.""" start="00:11:01.904" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""You can go to its definition or find references.""" start="00:11:05.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""Let's say we want to go to the definition of Monad.""" start="00:11:10.344" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""It jumps to the definition site of the monad type class.""" start="00:11:20.264" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""If we click at the definition site,""" start="00:11:25.584" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""it brings up a list of references.""" start="00:11:28.104" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""On the left, you can choose""" start="00:11:32.224" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""which package you want to find references of monad in.""" start="00:11:33.744" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""Let's look at the random one, avwx.""" start="00:11:39.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""Here is a list of results where Monad is used in avwx.""" start="00:11:47.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""This is a module path.""" start="00:11:54.144" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""One can go to any of these results.""" start="00:11:57.864" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""We can search for things in all packages""" start="00:12:06.424" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""or in the current package.""" start="00:12:07.944" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""Let’s say I want to search for "Read"""" start="00:12:09.584" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""I think this is the "Read" that is commonly used in Haskell,""" start="00:12:13.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""the read type class for parsing strings into values.""" start="00:12:19.344" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""I think that is more or less it.""" start="00:12:25.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""That is the Haskell Code Explorer web application""" start="00:12:31.104" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""in all its glory.""" start="00:12:34.624" video="mainVideo-haskell" id="subtitle"]] +[[!template new="1" text="""Let's go back to the slides.""" start="00:12:38.304" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""That was the web application,""" start="00:12:40.984" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""which is basically a JavaScript client""" start="00:12:43.464" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""that talks to the server""" start="00:12:46.544" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""by sending requests and receiving""" start="00:12:48.744" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""and parsing the JSON results or JSON responses.""" start="00:12:51.064" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""Initially, I was interested in hacking the web client.""" start="00:12:55.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""It uses the ember.js web framework.""" start="00:13:02.504" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""The first thing to do was to npm install ember-cli.""" start="00:13:05.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""It gives me 12 vulnerabilities,""" start="00:13:09.944" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""4 low, 2 moderate, 3 high, 3 critical.""" start="00:13:16.224" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""I don't know how often it is the case""" start="00:13:19.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""when we don't really care about these nasty vulnerabilities""" start="00:13:26.184" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""from Node.js or npm because they are so common.""" start="00:13:33.064" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""I don't quite like that.""" start="00:13:36.000" video="mainVideo-haskell" id="subtitle"]] +[[!template new="1" text="""Another reason for favoring Emacs clients""" start="00:13:41.144" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""over JavaScript clients is user freedom.""" start="00:13:45.464" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""Emacs is geared towards user freedom.""" start="00:13:49.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""It allows users maximum freedom to customize or mod Emacs.""" start="00:13:53.384" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""I think Emacs clients can be a way to fix JavaScript traps,""" start="00:14:01.664" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""like using user scripts to replace non-free JavaScript.""" start="00:14:07.264" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""There are tools to do that, for example, like Haketilo.""" start="00:14:14.344" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""Why write JavaScript replacement""" start="00:14:19.584" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""if we can write Elisp replacement?""" start="00:14:21.504" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""If we overwrite all kinds of front-ends in Emacs""" start="00:14:25.264" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""for commonly-used web applications""" start="00:14:31.784" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""like Reddit, Hacker News, what have you,""" start="00:14:34.504" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""then we have an Emacs app store""" start="00:14:37.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""where we can just install these applications""" start="00:14:40.904" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""and browse the web more freely.""" start="00:14:43.704" video="mainVideo-haskell" id="subtitle"]] +[[!template new="1" text="""Back to hcel, which is the Emacs client I wrote.""" start="00:14:51.184" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""I tried to reuse as much of Emacs built-ins as possible,""" start="00:14:56.144" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""including eldoc, for showing documentation,""" start="00:14:59.184" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""xref for cross-referencer,""" start="00:15:03.144" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""compilation-mode for showing search results of identifiers,""" start="00:15:04.864" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""outline-mode for a hierarchical view""" start="00:15:07.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""of package module identifiers,""" start="00:15:11.704" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""sort of a cursor-mode for highlighting identifiers,""" start="00:15:14.384" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""help-mode for displaying quick help for Haskell identifiers,""" start="00:15:18.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""integration with haddorg,""" start="00:15:26.144" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""which I will mention later, etc.""" start="00:15:27.704" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""It is available as hcel without the dot on GNU ELPA.""" start="00:15:31.304" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""Time for a demo.""" start="00:15:38.000" video="mainVideo-haskell" id="subtitle"]] +[[!template new="1" text="""To start using hc.el, surprise surprise,""" start="00:15:40.184" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""we run the hcel command.""" start="00:15:42.584" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""We are presented with a list of packages""" start="00:15:45.184" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""indexed by the hcel indexer.""" start="00:15:46.984" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""This is an outline mode,""" start="00:15:52.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""so we can tab to list all the modules""" start="00:15:54.064" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""represented by the module path.""" start="00:15:58.824" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""We can further tab into the list of identifiers""" start="00:16:01.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""declared in this module.""" start="00:16:03.504" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""Now it asks whether you want to open module source.""" start="00:16:05.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""This is because some module source code""" start="00:16:09.184" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""can be quite large and it can take a bit of time.""" start="00:16:11.984" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""In this case, the control monad is quite small,""" start="00:16:14.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""so let's say yes.""" start="00:16:17.784" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""We see the list of identifiers.""" start="00:16:19.944" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""One can jump to an identifier forever.""" start="00:16:24.104" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""As you can see, the identifiers at points are highlighted.""" start="00:16:28.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""This can be particularly useful""" start="00:16:33.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""in a large function declaration""" start="00:16:36.224" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""where you come to see, for example,""" start="00:16:38.704" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""all the occurrences of an identifier""" start="00:16:40.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""inside the body of the declaration.""" start="00:16:44.304" video="mainVideo-haskell" id="subtitle"]] +[[!template new="1" text="""These are declarations""" start="00:16:48.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""which in Haskell mode are listed in imenu.""" start="00:16:50.824" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""We can do the same here in hcel source mode.""" start="00:16:53.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""It lists all the declarations with their signature.""" start="00:17:00.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""Let's say we want to jump to this funny operator.""" start="00:17:06.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""It worked and you can also go back and forth""" start="00:17:13.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""within the declarations by pressing "n" and "p".""" start="00:17:20.424" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""Similarly, you can do something similar in the outline mode""" start="00:17:26.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""by toggling the follow mode, just like in org-agenda.""" start="00:17:30.904" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""Let's turn it off.""" start="00:17:38.000" video="mainVideo-haskell" id="subtitle"]] +[[!template new="1" text="""Now, how about find definition references?""" start="00:17:40.224" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""Using xref,""" start="00:17:46.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""we can jump to the definition of Int and jump back.""" start="00:17:49.064" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""Jump to Maybe, jump back.""" start="00:17:53.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""Let's have a look at references of replicateM.""" start="00:17:56.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""There are plenty of them.""" start="00:18:01.024" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""Maybe we want to check out ghc-lib.""" start="00:18:03.464" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""Here are all the references""" start="00:18:09.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""and you can of course jump to any of them in the results.""" start="00:18:11.344" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""Cool.""" start="00:18:16.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""You may have already noticed""" start="00:18:19.000" video="mainVideo-haskell" id="subtitle"]] +[[!template new="1" text="""the eldoc displaying the documentation""" start="00:18:21.864" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""and signature of identifiers.""" start="00:18:27.184" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""For example, here it shows the signature of replicateM,""" start="00:18:34.904" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""where it is defined, and its documentation.""" start="00:18:44.104" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""We can bring up the eldoc buffer.""" start="00:18:47.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""In the eldoc buffer,""" start="00:18:56.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""there are also links to other identifiers,""" start="00:18:58.264" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""which takes you to the definition of these identifiers,""" start="00:19:00.184" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""like minBound.""" start="00:19:04.544" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""Apparently, this is not working.""" start="00:19:07.624" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""I'm pretty sure it maybe works.""" start="00:19:10.864" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""Let's go to nothing or just...""" start="00:19:13.104" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""I think those didn't work because""" start="00:19:17.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""the module source for those identifiers is not open.""" start="00:19:19.864" video="mainVideo-haskell" id="subtitle"]] +[[!template new="1" text="""Of course, you can search""" start="00:19:24.144" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""for any identifiers across all indexed packages""" start="00:19:30.304" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""by invoking hcel-global-ids.""" start="00:19:33.024" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""Let's say we want to search for Read.""" start="00:19:38.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""We are presented with a list of results,""" start="00:19:42.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""which are identifiers starting with Read with capital R.""" start="00:19:47.464" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""They also show where they are defined""" start="00:19:54.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""and the documentation, just like in eldoc.""" start="00:19:57.304" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""One can also directly jump to the identifier""" start="00:20:07.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""in the mini-buffer results.""" start="00:20:13.944" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""For example, we want to check out this Read2""" start="00:20:20.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""defined in base-4.12.0.0 Data.Functor.Classes""" start="00:20:22.024" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""There we go.""" start="00:20:28.000" video="mainVideo-haskell" id="subtitle"]] +[[!template new="1" text="""Another functionality of hcel""" start="00:20:34.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""is the help buffer integration.""" start="00:20:37.864" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""We can do hcel-help and then let's say""" start="00:20:41.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""we want to learn about the read type class.""" start="00:20:46.565" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""This is a help buffer""" start="00:20:52.744" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""and you can jump to other definitions""" start="00:20:55.184" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""within the help buffer""" start="00:21:00.904" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""to read the documentation like readsPrec.""" start="00:21:02.464" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""It says Server version cannot be satistifed. Actual version.""" start="00:21:07.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""This means we need to tell hecl""" start="00:21:11.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""that the server has the correct version.""" start="00:21:14.784" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""hecl-fetch-server-version.""" start="00:21:17.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""Wait a bit for it to update""" start="00:21:21.744" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""the knowledge of the server version.""" start="00:21:25.704" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""Now you can follow the links, Read, readsPrec.""" start="00:21:27.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""You can do the "l" and "r" to navigate within the history.""" start="00:21:33.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""ReadS, ReadP.""" start="00:21:38.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""Just like in the help buffer for elisp code,""" start="00:21:43.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""you can jump to the definition.""" start="00:21:46.024" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""I believe that is everything, more or less.""" start="00:21:53.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""That concludes the demo.""" start="00:22:00.000" video="mainVideo-haskell" id="subtitle"]] +[[!template new="1" text="""Now let's turn to haddorg,""" start="00:22:05.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""which is an Org backend for Haddock.""" start="00:22:07.144" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""Haddock is the documentation generator for Haskell packages.""" start="00:22:09.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""For example,""" start="00:22:13.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""the official Haskell package documentation website Hackage,""" start="00:22:15.144" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""all the documentation there is generated by Haddock""" start="00:22:22.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""into the HTML format.""" start="00:22:25.904" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""Haddock has several backends""" start="00:22:28.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""that convert the intermediate representation""" start="00:22:31.424" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""called interface to various output formats,""" start="00:22:34.384" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""including HTML, LaTeX, and Hugo.""" start="00:22:37.064" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""HTML is the main format with a lot of features.""" start="00:22:41.864" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""LaTeX is less so, and I don't think it is widely used.""" start="00:22:44.904" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""Let's have a look at an HTML example.""" start="00:22:49.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""This is a PDF because these HTML files can be rather large""" start="00:22:53.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""and slow down EWW significantly.""" start="00:23:01.184" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""It's faster to convert it to PDF""" start="00:23:07.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""and read it from pdf-tools.""" start="00:23:10.264" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""Looks like this is as big as it goes.""" start="00:23:17.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""I hope you can still see it.""" start="00:23:20.864" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""Can I still enlarge it a bit more? Maybe.""" start="00:23:26.144" video="mainVideo-haskell" id="subtitle"]] +[[!template new="1" text="""This is Servant.Server.""" start="00:23:30.144" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""It is a module in the servant-server package.""" start="00:23:33.064" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""It is a widely used package for writing servers.""" start="00:23:36.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""It starts with a heading, which is the name of the module,""" start="00:23:42.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""and the table of contents.""" start="00:23:49.904" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""Then a heading: Run an wai application from an API.""" start="00:23:52.784" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""Under this heading, there are all the relevant identifiers""" start="00:23:56.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""that is concerned with running a WAI application from API,""" start="00:24:00.904" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""including serve, which is one of the main entry points""" start="00:24:08.624" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""for a Servant.Server.""" start="00:24:13.304" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""It has a signature linkable to the other identifiers,""" start="00:24:15.624" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""the documentation,""" start="00:24:21.704" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""an example with a Haskell source code block.""" start="00:24:23.104" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""That's what HTML output looks like.""" start="00:24:26.744" video="mainVideo-haskell" id="subtitle"]] +[[!template new="1" text="""As I mentioned,""" start="00:24:31.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""there are several downsides or drawbacks with that,""" start="00:24:34.024" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""like the HTML files can be huge and slow down EWW.""" start="00:24:35.904" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""Also, every module is an HTML of itself,""" start="00:24:41.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""and there's also an HTML for the package""" start="00:24:46.224" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""with a list of all the modules.""" start="00:24:48.384" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""Whereas the Org backend""" start="00:24:50.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""is better in that it is much more compact.""" start="00:24:54.744" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""All the modules under the same package""" start="00:25:04.264" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""are included in one Org file""" start="00:25:07.504" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""as sub-headings, level 2 headings.""" start="00:25:10.784" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""So, servant-server, Servant.Server, that is the module.""" start="00:25:13.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""So basically, this level 2 heading""" start="00:25:19.504" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""contains all the information in this PDF.""" start="00:25:21.944" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""Run the WAI application from API, serve.""" start="00:25:25.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""It has a signature that links to other identifiers""" start="00:25:29.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""and the documentation that's also linkable.""" start="00:25:39.224" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""The Haskell source block is now an Org source block,""" start="00:25:42.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""and you can do all sorts of interesting things""" start="00:25:47.224" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""with it using org-babel.""" start="00:25:49.504" video="mainVideo-haskell" id="subtitle"]] +[[!template new="1" text="""Let's check the links as server.""" start="00:25:52.744" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""Right, so the link works.""" start="00:25:56.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""Application, right, Request.""" start="00:26:00.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""It also supports cross-packaging package linking,""" start="00:26:05.384" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""so following the link to request""" start="00:26:08.384" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""takes us from servant-server package Org documentation""" start="00:26:12.304" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""to the WAI Org documentation.""" start="00:26:17.624" video="mainVideo-haskell" id="subtitle"]] +[[!template new="1" text="""Another nice thing with Org documentation""" start="00:26:24.784" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""is that you can use Org functions""" start="00:26:27.544" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""like org-goto to jump to any identifiers.""" start="00:26:32.744" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""Let's say we want to jump to application.""" start="00:26:40.544" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""We have toApplication. So it jumpts to toApplication.""" start="00:26:45.904" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""I guess application is not an identifier,""" start="00:26:50.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""yes, it is more like a type alias,""" start="00:26:54.024" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""that's why we couldn't find it.""" start="00:26:55.824" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""So that is haddorg.""" start="00:26:58.664" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""And of course, I implemented a bit of integration""" start="00:27:01.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""between haddorg and hcel""" start="00:27:06.104" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""so that we can jump from one to the other.""" start="00:27:08.544" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""Let's go back to servant.""" start="00:27:11.304" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""Let's see, ServerT.""" start="00:27:15.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""Maybe we want to check out""" start="00:27:24.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""the source code definition of ServerT.""" start="00:27:27.104" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""To find out exactly what sort of type alias it is,""" start="00:27:31.944" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""like what is the alias (or type synonym)""" start="00:27:36.264" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""We run hcel-identifier-at-point--""" start="00:27:43.184" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""sorry, hcel-haddorg-to-hcel-definition...""" start="00:27:49.504" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""Oh, we have an HTTP error.""" start="00:27:52.344" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""Typ ServerT not found in module src/Servant/Server.hs""" start="00:27:55.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""Why? Well, this is because""" start="00:27:59.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""the HCEL server only understands,""" start="00:28:01.125" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""it only has knowledge of identifiers""" start="00:28:04.944" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""that is defined in the original source file.""" start="00:28:07.824" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""So, it is not aware of, say,""" start="00:28:12.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""identifiers that are re-exported in the module.""" start="00:28:17.184" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""Most likely, Servant.Server module re-exports ServerT""" start="00:28:21.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""from another module.""" start="00:28:25.824" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""We will probably have better luck""" start="00:28:28.704" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""looking into some internal modules like this one.""" start="00:28:29.744" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""Let's try this type class HasContextEntry.""" start="00:28:35.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""So this time it worked.""" start="00:28:39.000" video="mainVideo-haskell" id="subtitle"]] +[[!template new="1" text="""And, of course, we can go the other direction""" start="00:28:42.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""from hecl to haddorg.""" start="00:28:44.344" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""Let's say if we want to display named context""" start="00:28:48.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""in the haddorg documentation""" start="00:28:51.584" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""so that we can read about, other identifiers documentation""" start="00:28:54.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""that is related to named context.""" start="00:29:01.624" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""We do hecl-identifier-at-point-to-haddorg""" start="00:29:04.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""And it does take us to the server-server old file.""" start="00:29:08.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""Okay.""" start="00:29:14.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""And that concludes my presentation.""" start="00:29:18.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""You can find hecl in GNU Elpa,""" start="00:29:21.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""and you can also find the source code,""" start="00:29:23.584" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""as well as the source of haddorg""" start="00:29:25.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""and instructions on how to generate org documentation""" start="00:29:27.464" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""using haddorg in my cgit instance.""" start="00:29:29.864" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""Thank you for your attention.""" start="00:29:33.000" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""I hope you enjoy the rest of the conference.""" start="00:29:36.784" video="mainVideo-haskell" id="subtitle"]] +[[!template text="""Thank you.""" start="00:29:38.000" video="mainVideo-haskell" id="subtitle"]] + +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) |