Hi, I’ve been thinking about how to improve library documentation and found that I – at least – really like to read the examples in the docs first and foremost, as they provide a lot of information in little time.
But writing documentation (and examples in the docs) is annoying - especially because they can easily get outdated, as they are not tested.
My idea is to generate tests from the examples in the doc comments. A PoC-Implementaion can be found here: https://github.com/csicar/purescript-doctest
Take for example the documentation of Array.fromFoldable
, which looks like this:
Array.fromFoldable (Just 1) = [1]
We could then parse this docs-comment and generate a test-file, that looks like this:
…
main = suite "Array" $ do
it "Spec : fromFoldable" $
Array.fromFoldable (Just 1) `shouldEqual` [1]
Making it practical
No defined Synax & Semantics
Parsing such an example would be hard, as =
can serve the purpose of declaring a variable and asserting equality (like here).
Examples often also assume, that some imports have magically appeared (like Just
in the example above).
Sometimes it is useful to show the reader what type an expression has. I’ve used -- :: TypeOfTheThing
instead of :: TypeOfTheThing
in the past, as it shows, that specifying a type is not required. But this again has no well-defined semantics.
Some examples aren’t and shouldn’t be runnable tests
Sometimes it is useful so have “handwavy” examples with ellipses and abstractions applied to them, which means we need a way to distinguish between “runnable” and “handwavy” examples
Examples must be easy to read and write
Both reader and writer of examples should not need to learn a new language.
PSCI-Logs as a solution?
Luckily we already PSCI with well-defined syntax and semantics, which is understood by most purescript programmers. PSCI also supports showing the value of an expression and showing a type with :t
.
The idea is to use the logs from a PSCI-Session as the content of examples in the docs:
> Array.fromFoldable (Just 1)
[1]
This makes it clear, which part is input (everything after >
) and what part of the output (and should be asserted in a test).
This also works for types, of course:
> import Data.Maybe
> :t Nothing <> Just []
forall t4. Maybe (Array t4)
The syntax used by the PoC is actually to similar to PSCI, that I was able to reuse the PSCI-Command parser, that is build into purs.