Setting out to think about a tool that generates documentation from nix modules, the first thing that we (@a-kenji, @vimal and I) figured out is that whatever values are provided by nix module is determined by evaluation of it. There are no static items. Everything is an expression.
The only non-hacky way (of obtaining documentation from nix code) I can think of, is by evaluating the code. Otherwise, we are resorting to various “well, if the AST is exactly this or that way” and such. And I don’t find that appealing.
Or, should we have static items in the language to solve this problem?
Well, what I imagine to be most ergonomic from the contributor’s perspective, and closest to what we have already, is to have documentation naturally in the comments. For example:
# make a qux
{
# a foo
foo
# some bar
, bar
# a baz to use
, baz ? none
}:
# ...
That may come with types:
# make a qux
{
# list of foobles
foo # :: [String]
# some bar
, bar # :: Bool
# a baz to use
, baz ? none # :: Derivation
}:
# ...
I’m not an expert but what is wrong with evaluating the module? Thanks to laziness I guess that you can only evaluate the parts of the module that are needed for the documentation, and you certainly don’t need to provide meaningfull arguments since the rest of the module will not be evaluated. And I guess that lib.mkOption provides the necessary interface to recover the type that was provided to lib.mkOption, since you define a new option with something like:
While looking into the theory of this, @fricklerhandwerk helped me reach the understanding that due to the dynamic nature of the language, the return type of a function might not be statically analyzable.
Even an approach of partial evaluation by the interpreter doesn’t solve this problem.
What remains to be seen is how frequently this is the case. Can anyone with exposure to a lot of Nix code shed some light, here, please?
Can anyone from nix-doc share their insights, please?