WEBVTT captioned by anush

00:00.000 --> 00:03.499
Today, I will talk about Haskell code exploration for Emacs.

00:03.500 --> 00:06.499
What is Haskell? It is a purely functional language.

00:06.500 --> 00:09.499
For example, every value in Haskell is immutable.

00:09.500 --> 00:12.999
And it is the main compiler of Haskell, GHC.

00:13.000 --> 00:15.999
It provides API for the whole compilation pipeline.

00:16.000 --> 00:00:18.324
For example, the tools mentioned in this talk,

00:00:18.424 --> 00:00:19.999
including hcel and haddorg,

00:20.000 --> 00:24.499
they use, they heavily utilize the GHC front-end API

00:24.500 --> 00:00:26.644
for parsing and understanding

00:00:26.744 --> 00:00:29.499
the identifiers in Haskell source files.

00:29.500 --> 00:00:31.444
Roughly speaking,

00:00:31.544 --> 00:00:34.564
a Haskell program consists of several parts.

00:00:34.664 --> 00:00:36.964
it begins with some front matters, including,

00:00:37.064 --> 00:00:39.924
for example, language extensions,

00:00:40.024 --> 00:00:43.964
which are optional language features one might want to use

00:00:44.064 --> 00:00:48.364
for convenience.

00:00:48.464 --> 00:00:52.499
The front matters also contain module exports.

00:52.500 --> 00:00:55.684
So for example, here we define,

00:00:55.784 --> 00:00:57.999
we declare module F2Md.Config

00:58.000 --> 00:01:00.884
for this Haskell source file,

00:01:00.984 --> 00:01:02.999
which exports these four identifiers

01:03.000 --> 01:07.499
that other source files can use when importing F2Md.Config.

01:07.500 --> 00:01:10.684
And the next will be

00:01:10.784 --> 00:01:13.999
a block of imports so that we can use libraries

01:14.000 --> 01:16.999
and identifiers in these libraries.

01:17.000 --> 00:01:21.644
The bulk of a Haskell source file normally is

00:01:21.744 --> 00:01:22.999
a list of declarations,

01:23.000 --> 01:25.999
including values, types, and instances, and so on.

01:26.000 --> 00:01:29.084
The difference between a value and a type is that

00:01:29.184 --> 00:01:30.499
the type of a value is a type,

01:30.500 --> 00:01:33.964
and the type of a type is a kind.

00:01:34.064 --> 00:01:38.484
For example, here's a small block of Haskell source code.

00:01:38.584 --> 00:01:41.404
We define Range type

00:01:41.504 --> 00:01:44.999
from a lower-end integer to a higher-end integer.

01:45.000 --> 00:01:51.364
We also declare a value r of the type Range,

00:01:51.464 --> 00:01:53.999
which is Range from 2 to 7,

01:54.000 --> 00:02:01.004
because in Haskell, we like to--

00:02:01.104 --> 00:02:03.999
by default, functions can be curried,

02:04.000 --> 00:02:09.804
which basically means, by default, we want to utilize

00:02:09.904 --> 00:02:11.999
the partial application of functions.

00:02:12.000 --> 00:02:17.284
We don't require parens surrounding arguments

00:02:17.384 --> 00:02:19.364
when invoking a function.

00:02:19.464 --> 00:02:22.724
That makes it possible, if you want,

00:02:22.725 --> 00:02:24.999
to write Haskell like Lisp

02:25.000 --> 02:27.999
by adding a bit of redundant parens.

02:28.000 --> 00:02:30.044
So for example,

00:02:30.144 --> 00:02:33.684
here are two blocks of code, one Lisp, one Haskell,

00:02:33.784 --> 00:02:35.999
and they look quite similar to each other.

02:36.000 --> 02:37.999
What is a code explorer?

02:38.000 --> 00:02:39.444
A code explorer is a tool

00:02:39.544 --> 00:02:42.624
to browse its code base to its code comprehension.

00:02:42.724 --> 00:02:45.324
Code explorer commonly comes with

00:02:45.424 --> 00:02:46.999
several functionalities or features,

02:47.000 --> 00:02:49.244
including a cross-referencer,

00:02:49.344 --> 00:02:52.999
which allows going to definitions of an identifier at points

02:53.000 --> 00:02:56.444
or looking up references of an identifier,

00:02:56.544 --> 00:02:57.999
like where it is used.

02:58.000 --> 03:03.999
So the example in Emacs would be xref.

03:04.000 --> 00:03:07.604
Code explorer also would be able to show you

00:03:07.704 --> 00:03:09.999
documentation and signatures of identifiers at points.

03:10.000 --> 00:03:13.884
In Emacs, that would be eldoc.

00:03:13.984 --> 00:03:16.999
It also commonly allows you to search for identifiers.

03:17.000 --> 00:03:19.884
Something like that in Emacs

00:03:19.984 --> 00:03:21.999
could be describe-function and find-function.

03:22.000 --> 00:03:24.684
Code explorer is normally

00:03:24.784 --> 00:03:27.364
quite often implemented in two parts,

00:03:27.464 --> 00:03:27.999
the indexer and the server,

03:28.000 --> 00:03:32.484
where the indexer parses the source code files,

00:03:32.584 --> 00:03:33.999
indexes the identifiers,

03:34.000 --> 00:03:36.284
and stores the information of identifiers

00:03:36.384 --> 00:03:37.999
like the definition, size, and the currencies,

03:38.000 --> 03:41.999
either in databases or in files.

03:42.000 --> 00:03:44.444
The other part is the server,

00:03:44.544 --> 00:03:48.999
which uses the database created by the indexer

03:49.000 --> 00:03:53.004
to serve the information of the identifier.

00:03:53.104 --> 00:03:57.004
Before I present my solution to code exploring,

00:03:57.104 --> 00:04:00.999
some description of prior art is in order.

04:01.000 --> 00:04:05.284
There are several tools that you can use

00:04:05.384 --> 00:04:07.999
to aid code exploration,

04:08.000 --> 00:04:13.444
including tech-based tools like hasktags and hs-tags.

00:04:13.544 --> 00:04:15.484
The limitation with these tools

00:04:15.584 --> 00:04:17.999
is they are focused on the current projects only

04:18.000 --> 00:04:19.604
and do not work

00:04:19.704 --> 00:04:25.999
for cross-packaging reference and definition.

04:26.000 --> 00:04:31.044
Another problem with the tag-based tools is

00:04:31.045 --> 00:04:34.684
they might not handle symbols with the same name properly.

00:04:34.784 --> 00:04:35.999
Sometimes they get confused,

04:36.000 --> 00:04:43.324
and they ask you to choose which definition,

00:04:43.424 --> 00:04:45.924
what is the correct definition site,

00:04:46.024 --> 00:04:49.244
even though the occurrence of the symbol

00:04:49.344 --> 00:04:54.999
or the symbol at point has only one definition ambiguously.

04:55.000 --> 04:57.999
Another tool is the haskell-mode.

04:58.000 --> 00:05:02.684
It has some limited support for eldoc

00:05:02.784 --> 00:05:06.604
by displaying the signature of an identifier at points,

00:05:06.704 --> 00:05:11.764
but the identifier has to be something

00:05:11.864 --> 00:05:14.999
that is commonly known or sort of built-in

05:15.000 --> 05:17.999
or come from the base library of Haskell.

05:18.000 --> 00:05:20.244
So for example,

00:05:20.344 --> 00:05:24.244
it works for common functions like head and tail.

00:05:24.344 --> 00:05:26.999
And you can see that the signature is displayed here.

05:27.000 --> 00:05:29.564
However, it does not work for,

00:05:29.664 --> 00:05:31.804
let's say, IO. IO is a type.

00:05:31.904 --> 00:05:32.999
Maybe that's the reason.

05:33.000 --> 00:05:37.324
Let's find another function

00:05:37.424 --> 00:05:39.999
that's not from the base library.

05:40.000 --> 05:41.999
toJSON is from the Aeson library,

05:42.000 --> 05:46.999
so no signature is displayed here.

05:47.000 --> 00:05:51.164
It also provides

00:05:51.264 --> 00:05:53.324
some sort of goto-declaration functionality

00:05:53.424 --> 00:05:56.324
to jump to any declaration in a file.

00:05:56.424 --> 00:06:00.564
To do that, one has to first run haskell-decl-scan-mode

00:06:00.664 --> 00:06:02.999
to enter this minor mode.

06:03.000 --> 00:06:08.044
Then we can run imenu to go to any definition,

00:06:08.144 --> 00:06:10.999
to go to any declaration, like getHomeR.

06:11.000 --> 00:06:13.724
Apparently, after running that,

00:06:13.824 --> 00:06:15.999
we are able to go to definition.

06:16.000 --> 06:18.999
So for example, let's see,

06:19.000 --> 06:21.999
we want to find definition of getCityJR.

06:22.000 --> 00:06:25.524
And indeed, it works

00:06:25.624 --> 00:06:28.524
if it's within the same source file, of course.

00:06:28.624 --> 00:06:31.999
It still does not work for cross-packaging identifiers.

06:32.000 --> 00:06:36.924
So HandlerFor is probably an identifier from servant.

00:06:37.024 --> 00:06:39.999
Or no, not necessarily servant. Maybe WAI.

06:40.000 --> 00:06:43.404
Anyway, it's another library.

00:06:43.504 --> 00:06:50.404
And how about find-references?

00:06:50.504 --> 00:07:01.124
find-references also works somehow for this file.

00:07:01.224 --> 00:07:06.684
How about WidgetFor?

00:07:06.784 --> 00:07:13.644
It works for WidgetFor too.

00:07:13.744 --> 00:07:17.999
It has some support for goto-definition and find-references.

07:18.000 --> 07:25.999
But as usual, it does not support such things cross-package.

07:26.000 --> 00:07:27.364
And finally, we have

00:07:27.365 --> 00:07:30.999
the Sledgehammer HLS Haskell language server.

07:31.000 --> 07:32.999
It can be used with EGLOT.

07:33.000 --> 00:07:40.804
But the problem with HLS, HLS has many many features

00:07:40.904 --> 00:07:42.844
because it is a language server,

00:07:42.944 --> 00:07:50.999
like renaming, like eldoc for standard libraries, and so on.

07:51.000 --> 07:56.999
But the problem with HLS is, one, that it is very, very slow.

07:57.000 --> 07:59.999
And I wouldn't use it with my laptop.

08:00.000 --> 08:04.999
And two, it also does not support cross-package referencing.

08:05.000 --> 08:07.999
In fact, there's an outstanding GitHub issue about this.

08:08.000 --> 00:08:12.964
So cross-package referencing and goto-definition

00:08:13.064 --> 00:08:17.164
is sort of a common shortfall,

00:08:17.264 --> 00:08:20.999
a common problem for these existing Haskell code explorers.

08:21.000 --> 08:22.999
Then finally, we also have hoogle and hackage.

08:23.000 --> 00:08:28.284
Hoogle is a search engine for Haskell identifiers,

00:08:28.384 --> 00:08:30.644
and the results link to Hackage,

00:08:30.744 --> 00:08:33.604
which is the Haskell documentation website

00:08:33.704 --> 00:08:34.999
for all Haskell libraries.

08:35.000 --> 00:08:40.004
Haskell Hackage has functionality

00:08:40.104 --> 00:08:44.999
where you can jump to the source code file rendered in HTML,

08:45.000 --> 00:08:49.444
and you can click on the identifiers there

00:08:49.544 --> 00:08:51.524
to jump to definitions,

00:08:51.624 --> 00:08:54.044
but it does not support find references,

00:08:54.144 --> 00:08:58.999
and it is rather basic.

08:59.000 --> 00:09:01.644
Then I learned about haskell-code-explorer,

00:09:01.744 --> 00:09:04.999
which is a fully-fledged Haskell code explorer.

09:05.000 --> 00:09:07.724
It is written by someone else.

00:09:07.824 --> 00:09:09.164
It is a web application

00:09:09.264 --> 00:09:11.999
for exploring Haskell package codebases.

09:12.000 --> 00:09:16.244
The official reference instance for haskell-code-explorer

00:09:16.344 --> 00:09:18.999
is available at this URL, which I will demo soon.

09:19.000 --> 09:24.999
What I did with these packages... I ported it to GHC 9.2.

09:25.000 --> 00:09:29.044
I renamed it to hcel because I want to focus on Emacs clients

00:09:29.144 --> 00:09:30.999
rather than JavaScript clients, which I will explain later.

09:31.000 --> 09:36.999
And I also wrote an Emacs client package, of course.

09:37.000 --> 00:09:41.404
This is what haskell-code-explorer looks like.

00:09:41.504 --> 00:09:46.924
On the homepage, it is a list of indexed packages

00:09:47.024 --> 00:09:50.044
indexed by the indexer.

00:09:50.144 --> 00:09:53.844
One can filter it by the package name

00:09:53.944 --> 00:10:04.999
or look for identifiers directly across all packages.

10:05.000 --> 00:10:09.884
Let's have a look at base. There are three versions.

00:10:09.984 --> 00:10:14.999
Let's have a look at the latest version, 4.12.0.0.

10:15.000 --> 00:10:18.964
Once entering the package view,

00:10:19.064 --> 00:10:24.444
you are shown a list of all modules by their path,

00:10:24.544 --> 00:10:28.999
as well as a tree of these module files.

10:29.000 --> 00:10:32.524
You can filter by module name or file name,

00:10:32.624 --> 00:10:34.324
or you can search for identifier within the same package

00:10:34.424 --> 00:10:35.999
or in all packages.

10:36.000 --> 00:10:43.204
Let's say we want to learn about Control.Monad.

00:10:43.304 --> 00:10:46.884
Now we are in the module view.

00:10:46.984 --> 00:10:49.804
The source file is presented to you,

00:10:49.904 --> 00:10:54.999
and it has links to identifiers.

10:55.000 --> 00:11:01.804
When you hover over them, the documentation shows up,

00:11:01.904 --> 00:11:04.999
including the signature where it is defined.

11:05.000 --> 00:11:10.244
You can go to its definition or find references.

00:11:10.344 --> 00:11:20.164
Let's say we want to go to the definition of Monad.

00:11:20.264 --> 00:11:25.484
It jumps to the definition site of the monad type class.

00:11:25.584 --> 00:11:28.004
If we click at the definition site,

00:11:28.104 --> 00:11:32.124
it brings up a list of references.

00:11:32.224 --> 00:11:33.644
On the left, you can choose

00:11:33.744 --> 00:11:38.999
which package you want to find references of monad in.

11:39.000 --> 11:46.999
Let's look at the random one, avwx.

11:47.000 --> 00:11:54.044
Here is a list of results where Monad is used in avwx.

00:11:54.144 --> 00:11:57.764
This is a module path.

00:11:57.864 --> 00:12:06.324
One can go to any of these results.

00:12:06.424 --> 00:12:07.844
We can search for things in all packages

00:12:07.944 --> 00:12:09.484
or in the current package.

00:12:09.584 --> 00:12:12.999
Let’s say I want to search for "Read"

12:13.000 --> 00:12:19.244
I think this is the "Read" that is commonly used in Haskell,

00:12:19.344 --> 00:12:24.999
the read type class for parsing strings into values.

12:25.000 --> 00:12:31.004
I think that is more or less it.

00:12:31.104 --> 00:12:34.524
That is the Haskell Code Explorer web application

00:12:34.624 --> 00:12:38.204
in all its glory.

00:12:38.304 --> 00:12:40.884
Let's go back to the slides.

00:12:40.984 --> 00:12:43.364
That was the web application,

00:12:43.464 --> 00:12:46.444
which is basically a JavaScript client

00:12:46.544 --> 00:12:48.644
that talks to the server

00:12:48.744 --> 00:12:50.964
by sending requests and receiving

00:12:51.064 --> 00:12:54.999
and parsing the JSON results or JSON responses.

12:55.000 --> 00:13:02.404
Initially, I was interested in hacking the web client.

00:13:02.504 --> 00:13:04.999
It uses the ember.js web framework.

13:05.000 --> 00:13:09.844
The first thing to do was to npm install ember-cli.

00:13:09.944 --> 00:13:16.124
It gives me 12 vulnerabilities,

00:13:16.224 --> 00:13:18.999
4 low, 2 moderate, 3 high, 3 critical.

13:19.000 --> 00:13:26.084
I don't know how often it is the case

00:13:26.184 --> 00:13:32.964
when we don't really care about these nasty vulnerabilities

00:13:33.064 --> 00:13:35.999
from Node.js or npm because they are so common.

13:36.000 --> 00:13:41.044
I don't quite like that.

00:13:41.144 --> 00:13:45.364
Another reason for favoring Emacs clients

00:13:45.464 --> 00:13:48.999
over JavaScript clients is user freedom.

13:49.000 --> 00:13:53.284
Emacs is geared towards user freedom.

00:13:53.384 --> 00:14:01.564
It allows users maximum freedom to customize or mod Emacs.

00:14:01.664 --> 00:14:07.164
I think Emacs clients can be a way to fix JavaScript traps,

00:14:07.264 --> 00:14:14.244
like using user scripts to replace non-free JavaScript.

00:14:14.344 --> 00:14:19.484
There are tools to do that, for example, like Haketilo.

00:14:19.584 --> 00:14:21.404
Why write JavaScript replacement

00:14:21.504 --> 00:14:25.164
if we can write Elisp replacement?

00:14:25.264 --> 00:14:31.684
If we overwrite all kinds of front-ends in Emacs

00:14:31.784 --> 00:14:34.404
for commonly-used web applications

00:14:34.504 --> 00:14:36.999
like Reddit, Hacker News, what have you,

14:37.000 --> 00:14:40.804
then we have an Emacs app store

00:14:40.904 --> 00:14:43.604
where we can just install these applications

00:14:43.704 --> 00:14:51.084
and browse the web more freely.

00:14:51.184 --> 00:14:56.044
Back to hcel, which is the Emacs client I wrote.

00:14:56.144 --> 00:14:59.084
I tried to reuse as much of Emacs built-ins as possible,

00:14:59.184 --> 00:15:03.044
including eldoc, for showing documentation,

00:15:03.144 --> 00:15:04.764
xref for cross-referencer,

00:15:04.864 --> 00:15:06.999
compilation-mode for showing search results of identifiers,

15:07.000 --> 00:15:11.604
outline-mode for a hierarchical view

00:15:11.704 --> 00:15:14.284
of package module identifiers,

00:15:14.384 --> 00:15:17.999
sort of a cursor-mode for highlighting identifiers,

15:18.000 --> 00:15:26.044
help-mode for displaying quick help for Haskell identifiers,

00:15:26.144 --> 00:15:27.604
integration with haddorg,

00:15:27.704 --> 00:15:31.204
which I will mention later, etc.

00:15:31.304 --> 00:15:37.999
It is available as hcel without the dot on GNU ELPA.

15:38.000 --> 00:15:40.084
Time for a demo.

00:15:40.184 --> 00:15:42.484
To start using hc.el, surprise surprise,

00:15:42.584 --> 00:15:45.084
we run the hcel command.

00:15:45.184 --> 00:15:46.884
We are presented with a list of packages

00:15:46.984 --> 00:15:51.999
indexed by the hcel indexer.

15:52.000 --> 00:15:53.964
This is an outline mode,

00:15:54.064 --> 00:15:58.724
so we can tab to list all the modules

00:15:58.824 --> 00:16:00.999
represented by the module path.

16:01.000 --> 00:16:03.404
We can further tab into the list of identifiers

00:16:03.504 --> 00:16:04.999
declared in this module.

16:05.000 --> 00:16:09.084
Now it asks whether you want to open module source.

00:16:09.184 --> 00:16:11.884
This is because some module source code

00:16:11.984 --> 00:16:13.999
can be quite large and it can take a bit of time.

16:14.000 --> 00:16:17.684
In this case, the control monad is quite small,

00:16:17.784 --> 00:16:19.844
so let's say yes.

00:16:19.944 --> 00:16:24.004
We see the list of identifiers.

00:16:24.104 --> 00:16:27.999
One can jump to an identifier forever.

16:28.000 --> 16:32.999
As you can see, the identifiers at points are highlighted.

16:33.000 --> 00:16:36.124
This can be particularly useful

00:16:36.224 --> 00:16:38.604
in a large function declaration

00:16:38.704 --> 00:16:39.999
where you come to see, for example,

16:40.000 --> 00:16:44.204
all the occurrences of an identifier

00:16:44.304 --> 00:16:47.999
inside the body of the declaration.

16:48.000 --> 00:16:50.724
These are declarations

00:16:50.824 --> 00:16:52.999
which in Haskell mode are listed in imenu.

16:53.000 --> 16:59.999
We can do the same here in hcel source mode.

17:00.000 --> 17:05.999
It lists all the declarations with their signature.

17:06.000 --> 17:12.999
Let's say we want to jump to this funny operator.

17:13.000 --> 00:17:20.324
It worked and you can also go back and forth

00:17:20.424 --> 00:17:25.999
within the declarations by pressing "n" and "p".

17:26.000 --> 00:17:30.804
Similarly, you can do something similar in the outline mode

00:17:30.904 --> 00:17:37.999
by toggling the follow mode, just like in org-agenda.

17:38.000 --> 00:17:40.124
Let's turn it off.

00:17:40.224 --> 00:17:45.999
Now, how about find definition references?

17:46.000 --> 00:17:48.964
Using xref,

00:17:49.064 --> 00:17:52.999
we can jump to the definition of Int and jump back.

17:53.000 --> 17:55.999
Jump to Maybe, jump back.

17:56.000 --> 00:18:00.924
Let's have a look at references of replicateM.

00:18:01.024 --> 00:18:03.364
There are plenty of them.

00:18:03.464 --> 00:18:08.999
Maybe we want to check out ghc-lib.

18:09.000 --> 00:18:11.244
Here are all the references

00:18:11.344 --> 00:18:15.999
and you can of course jump to any of them in the results.

18:16.000 --> 18:18.999
Cool.

18:19.000 --> 00:18:21.764
You may have already noticed

00:18:21.864 --> 00:18:27.084
the eldoc displaying the documentation

00:18:27.184 --> 00:18:34.804
and signature of identifiers.

00:18:34.904 --> 00:18:44.004
For example, here it shows the signature of replicateM,

00:18:44.104 --> 00:18:46.999
where it is defined, and its documentation.

18:47.000 --> 18:55.999
We can bring up the eldoc buffer.

18:56.000 --> 00:18:58.164
In the eldoc buffer,

00:18:58.264 --> 00:19:00.084
there are also links to other identifiers,

00:19:00.184 --> 00:19:04.444
which takes you to the definition of these identifiers,

00:19:04.544 --> 00:19:07.524
like minBound.

00:19:07.624 --> 00:19:10.764
Apparently, this is not working.

00:19:10.864 --> 00:19:13.004
I'm pretty sure it maybe works.

00:19:13.104 --> 00:19:16.999
Let's go to nothing or just...

19:17.000 --> 00:19:19.764
I think those didn't work because

00:19:19.864 --> 00:19:24.044
the module source for those identifiers is not open.

00:19:24.144 --> 00:19:30.204
Of course, you can search

00:19:30.304 --> 00:19:32.924
for any identifiers across all indexed packages

00:19:33.024 --> 00:19:37.999
by invoking hcel-global-ids.

19:38.000 --> 19:41.999
Let's say we want to search for Read.

19:42.000 --> 00:19:47.364
We are presented with a list of results,

00:19:47.464 --> 00:19:53.999
which are identifiers starting with Read with capital R.

19:54.000 --> 00:19:57.204
They also show where they are defined

00:19:57.304 --> 00:20:06.999
and the documentation, just like in eldoc.

20:07.000 --> 00:20:13.844
One can also directly jump to the identifier

00:20:13.944 --> 00:20:19.999
in the mini-buffer results.

20:20.000 --> 00:20:21.924
For example, we want to check out this Read2

00:20:22.024 --> 00:20:27.999
defined in base-4.12.0.0 Data.Functor.Classes

20:28.000 --> 20:33.999
There we go.

20:34.000 --> 00:20:37.764
Another functionality of hcel

00:20:37.864 --> 00:20:40.999
is the help buffer integration.

20:41.000 --> 00:20:46.564
We can do hcel-help and then let's say

00:20:46.565 --> 00:20:52.644
we want to learn about the read type class.

00:20:52.744 --> 00:20:55.084
This is a help buffer

00:20:55.184 --> 00:21:00.804
and you can jump to other definitions

00:21:00.904 --> 00:21:02.364
within the help buffer

00:21:02.464 --> 00:21:06.999
to read the documentation like readsPrec.

21:07.000 --> 21:10.999
It says Server version cannot be satistifed. Actual version.

21:11.000 --> 00:21:14.684
This means we need to tell hecl

00:21:14.784 --> 00:21:16.999
that the server has the correct version.

21:17.000 --> 00:21:21.644
hecl-fetch-server-version.

00:21:21.744 --> 00:21:25.604
Wait a bit for it to update

00:21:25.704 --> 00:21:26.999
the knowledge of the server version.

21:27.000 --> 21:32.999
Now you can follow the links, Read, readsPrec.

21:33.000 --> 21:37.999
You can do the "l" and "r" to navigate within the history.

21:38.000 --> 21:42.999
ReadS, ReadP.

21:43.000 --> 00:21:45.924
Just like in the help buffer for elisp code,

00:21:46.024 --> 00:21:52.999
you can jump to the definition.

21:53.000 --> 21:59.999
I believe that is everything, more or less.

22:00.000 --> 22:04.999
That concludes the demo.

22:05.000 --> 00:22:07.044
Now let's turn to haddorg,

00:22:07.144 --> 00:22:08.999
which is an Org backend for Haddock.

22:09.000 --> 22:12.999
Haddock is the documentation generator for Haskell packages.

22:13.000 --> 00:22:15.044
For example,

00:22:15.144 --> 00:22:21.999
the official Haskell package documentation website Hackage,

22:22.000 --> 00:22:25.804
all the documentation there is generated by Haddock

00:22:25.904 --> 00:22:27.999
into the HTML format.

22:28.000 --> 00:22:31.324
Haddock has several backends

00:22:31.424 --> 00:22:34.284
that convert the intermediate representation

00:22:34.384 --> 00:22:36.964
called interface to various output formats,

00:22:37.064 --> 00:22:41.764
including HTML, LaTeX, and Hugo.

00:22:41.864 --> 00:22:44.804
HTML is the main format with a lot of features.

00:22:44.904 --> 00:22:48.999
LaTeX is less so, and I don't think it is widely used.

22:49.000 --> 22:52.999
Let's have a look at an HTML example.

22:53.000 --> 00:23:01.084
This is a PDF because these HTML files can be rather large

00:23:01.184 --> 00:23:06.999
and slow down EWW significantly.

23:07.000 --> 00:23:10.164
It's faster to convert it to PDF

00:23:10.264 --> 00:23:16.999
and read it from pdf-tools.

23:17.000 --> 00:23:20.764
Looks like this is as big as it goes.

00:23:20.864 --> 00:23:26.044
I hope you can still see it.

00:23:26.144 --> 00:23:30.044
Can I still enlarge it a bit more? Maybe.

00:23:30.144 --> 00:23:32.964
This is Servant.Server.

00:23:33.064 --> 00:23:35.999
It is a module in the servant-server package.

23:36.000 --> 23:41.999
It is a widely used package for writing servers.

23:42.000 --> 00:23:49.804
It starts with a heading, which is the name of the module,

00:23:49.904 --> 00:23:52.684
and the table of contents.

00:23:52.784 --> 00:23:55.999
Then a heading: Run an wai application from an API.

23:56.000 --> 00:24:00.804
Under this heading, there are all the relevant identifiers

00:24:00.904 --> 00:24:08.524
that is concerned with running a WAI application from API,

00:24:08.624 --> 00:24:13.204
including serve, which is one of the main entry points

00:24:13.304 --> 00:24:15.524
for a Servant.Server.

00:24:15.624 --> 00:24:21.604
It has a signature linkable to the other identifiers,

00:24:21.704 --> 00:24:23.004
the documentation,

00:24:23.104 --> 00:24:26.644
an example with a Haskell source code block.

00:24:26.744 --> 00:24:30.999
That's what HTML output looks like.

24:31.000 --> 00:24:33.924
As I mentioned,

00:24:34.024 --> 00:24:35.804
there are several downsides or drawbacks with that,

00:24:35.904 --> 00:24:40.999
like the HTML files can be huge and slow down EWW.

24:41.000 --> 00:24:46.124
Also, every module is an HTML of itself,

00:24:46.224 --> 00:24:48.284
and there's also an HTML for the package

00:24:48.384 --> 00:24:49.999
with a list of all the modules.

24:50.000 --> 00:24:54.644
Whereas the Org backend

00:24:54.744 --> 00:25:04.164
is better in that it is much more compact.

00:25:04.264 --> 00:25:07.404
All the modules under the same package

00:25:07.504 --> 00:25:10.684
are included in one Org file

00:25:10.784 --> 00:25:12.999
as sub-headings, level 2 headings.

25:13.000 --> 00:25:19.404
So, servant-server, Servant.Server, that is the module.

00:25:19.504 --> 00:25:21.844
So basically, this level 2 heading

00:25:21.944 --> 00:25:24.999
contains all the information in this PDF.

25:25.000 --> 25:28.999
Run the WAI application from API, serve.

25:29.000 --> 00:25:39.124
It has a signature that links to other identifiers

00:25:39.224 --> 00:25:41.999
and the documentation that's also linkable.

25:42.000 --> 00:25:47.124
The Haskell source block is now an Org source block,

00:25:47.224 --> 00:25:49.404
and you can do all sorts of interesting things

00:25:49.504 --> 00:25:52.644
with it using org-babel.

00:25:52.744 --> 00:25:55.999
Let's check the links as server.

25:56.000 --> 25:59.999
Right, so the link works.

26:00.000 --> 00:26:05.284
Application, right, Request.

00:26:05.384 --> 00:26:08.284
It also supports cross-packaging package linking,

00:26:08.384 --> 00:26:12.204
so following the link to request

00:26:12.304 --> 00:26:17.524
takes us from servant-server package Org documentation

00:26:17.624 --> 00:26:24.684
to the WAI Org documentation.

00:26:24.784 --> 00:26:27.444
Another nice thing with Org documentation

00:26:27.544 --> 00:26:32.644
is that you can use Org functions

00:26:32.744 --> 00:26:40.444
like org-goto to jump to any identifiers.

00:26:40.544 --> 00:26:45.804
Let's say we want to jump to application.

00:26:45.904 --> 00:26:49.999
We have toApplication. So it jumpts to toApplication.

26:50.000 --> 00:26:53.924
I guess application is not an identifier,

00:26:54.024 --> 00:26:55.724
yes, it is more like a type alias,

00:26:55.824 --> 00:26:58.564
that's why we couldn't find it.

00:26:58.664 --> 00:27:00.999
So that is haddorg.

27:01.000 --> 00:27:06.004
And of course, I implemented a bit of integration

00:27:06.104 --> 00:27:08.444
between haddorg and hcel

00:27:08.544 --> 00:27:11.204
so that we can jump from one to the other.

00:27:11.304 --> 00:27:14.999
Let's go back to servant.

27:15.000 --> 27:23.999
Let's see, ServerT.

27:24.000 --> 00:27:27.004
Maybe we want to check out

00:27:27.104 --> 00:27:31.844
the source code definition of ServerT.

00:27:31.944 --> 00:27:36.164
To find out exactly what sort of type alias it is,

00:27:36.264 --> 00:27:43.084
like what is the alias (or type synonym)

00:27:43.184 --> 00:27:49.404
We run hcel-identifier-at-point--

00:27:49.504 --> 00:27:52.244
sorry, hcel-haddorg-to-hcel-definition...

00:27:52.344 --> 00:27:54.999
Oh, we have an HTTP error.

27:55.000 --> 27:58.999
Typ ServerT not found in module src/Servant/Server.hs

27:59.000 --> 00:28:01.124
Why? Well, this is because

00:28:01.125 --> 00:28:04.844
the HCEL server only understands,

00:28:04.944 --> 00:28:07.724
it only has knowledge of identifiers

00:28:07.824 --> 00:28:11.999
that is defined in the original source file.

28:12.000 --> 00:28:17.084
So, it is not aware of, say,

00:28:17.184 --> 00:28:20.999
identifiers that are re-exported in the module.

28:21.000 --> 00:28:25.724
Most likely, Servant.Server module re-exports ServerT

00:28:25.824 --> 00:28:28.604
from another module.

00:28:28.704 --> 00:28:29.644
We will probably have better luck

00:28:29.744 --> 00:28:34.999
looking into some internal modules like this one.

28:35.000 --> 28:38.999
Let's try this type class HasContextEntry.

28:39.000 --> 28:41.999
So this time it worked.

28:42.000 --> 00:28:44.244
And, of course, we can go the other direction

00:28:44.344 --> 00:28:47.999
from hecl to haddorg.

28:48.000 --> 00:28:51.484
Let's say if we want to display named context

00:28:51.584 --> 00:28:53.999
in the haddorg documentation

28:54.000 --> 00:29:01.524
so that we can read about, other identifiers documentation

00:29:01.624 --> 00:29:03.999
that is related to named context.

29:04.000 --> 29:07.999
We do hecl-identifier-at-point-to-haddorg

29:08.000 --> 29:13.999
And it does take us to the server-server old file.

29:14.000 --> 29:17.999
Okay.

29:18.000 --> 29:20.999
And that concludes my presentation.

29:21.000 --> 00:29:23.484
You can find hecl in GNU Elpa,

00:29:23.584 --> 00:29:24.999
and you can also find the source code,

29:25.000 --> 00:29:27.364
as well as the source of haddorg

00:29:27.464 --> 00:29:29.764
and instructions on how to generate org documentation

00:29:29.864 --> 00:29:32.999
using haddorg in my cgit instance.

29:33.000 --> 00:29:36.684
Thank you for your attention.

00:29:36.784 --> 00:29:37.999
I hope you enjoy the rest of the conference.

29:38.000 --> 29:51.000
Thank you.