Documenting Dhall expressions


#1

Hi all,

As https://github.com/dhall-lang/dhall-lang/pull/689 approaches completion, we’re starting to be in a good place for a basic module system. As such, I think it’s time we start thinking about documentation. I’ve been looking at what other new languages are doing for this, and both Rust and Idris have special documentation comments, and I think that might be the easiest thing for us.

I propose extending the grammar with new type of comment: ---. This can be attached to any expression, and in fact requires an expression to follow it. We then write dhall doc or something that knows how to turn such a --- annotated AST into HTML or something. Taking the prelude, we might have:

--- The Prelude provides extended functionality for working with Dhall types.
{ List = ./List/package.dhall, Bool = ./Bool/package.dhall }

This would generate some documentation for package.dhall, beginning with a header formed by the --- comment on the record. Next, there would be the documentation for the record itself. At the very least, it needs to show the keys of the record. I have some ideas for what else could go here, but I haven’t fleshed those ideas out yet.

Assuming there is a link to ./List/package.dhall, the user can follow a link to see its documentation. ./List/package.dhall probably doesn’t change (other than having a header), but each the individual functions probably have documentation:

--- Render a `Bool` as `Text` using the same representation as Dhall source
--- code (i.e. beginning with a capital letter)

let show : Bool → Text = λ(b : Bool) → if b then "True" else "False"

let example0 = assert : show True ≡ "True"

let example1 = assert : show False ≡ "False"

in  show

It would probably be nice to show the examples, so I wonder if --- should support interpolation somehow. One option is that --- uses reStructureText with a custom example directive:

--- Render a `Bool` as `Text` using the same representation as Dhall source
--- code (i.e. beginning with a capital letter)
---
--- Examples
--- ========
---
---   - .. example:: example0
---
---   - .. example:: example1

let show : Bool → Text = λ(b : Bool) → if b then "True" else "False"

let example0 = assert : show True ≡ "True"

let example1 = assert : show False ≡ "False"

in  show

This is in a sense not well scoped, so it might be better to move the documentation annotation to the show in in show - at that point example0 is actually in scope. dhall doc would have to document “under lets”, but that seems like it could work.


As a first step, I think we need a standard change that adds --- to document an expression. The rest can be explored in dhall doc, outside the documentation.

How do people feel about this? I may explore this on a separate dhall-haskell branch to see if it works.


#2

I’ve pushed a little MVP here: https://github.com/circuithub/dhall-haskell/tree/dhall-doc

Currently it supports ||| documentation comments (--- was chomped by the normal comment parser). There is a dhall doc command that just shows the header for an expression:

[nix-shell:~/work/dhall-haskell/dhall]$ cabal new-run exe:dhall <<'EOF'
||| The boolean value 'True'


True
EOF

True

[nix-shell:~/work/dhall-haskell/dhall]$ cabal new-run exe:dhall -- doc <<'EOF'
||| The boolean value 'True'


True
EOF

The boolean value 'True'

[nix-shell:~/work/dhall-haskell/dhall]$ cabal new-run exe:dhall -- format <<'EOF'
||| The boolean value 'True'


True
EOF

||| The boolean value 'True'
True

#3

Does this require changes to the language standard?

It seems like this could be implemented entirely within one language implementation (e.g. the Haskell implementation) which could provide a command-line executable or service for generating documentation that other implementations could reuse.


#4

I’m not sure. I guess at the moment --- is just a comment to any implementation, so the Haskell code could treat --- specially (but still erase it in normalisation) and it would still be standard compliant.

I’ll have a think on that!