Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[RFC 0145] Doc-comments #145

Merged
merged 116 commits into from
Nov 29, 2023
Merged
Changes from 2 commits
Commits
Show all changes
116 commits
Select commit Hold shift + click to select a range
af461dd
init: rfc about docs-string format
hsjobeki Mar 29, 2023
dee60aa
init: rfc number
hsjobeki Mar 29, 2023
4508831
fix some major spelling issues
hsjobeki Mar 29, 2023
34bf50e
gramatical cleanup
hsjobeki Mar 29, 2023
130d9e5
gramatical cleanup
hsjobeki Mar 29, 2023
ab0aa26
fix: consistent naming: doc-string(s)
hsjobeki Mar 29, 2023
2b0dea2
Update rfcs/0145-doc-strings.md
hsjobeki Mar 29, 2023
a3ee89a
make statement more clear
hsjobeki Mar 29, 2023
e1a7475
add statement what a sections is
hsjobeki Mar 29, 2023
d7e0cf5
remove empty example
hsjobeki Mar 29, 2023
4d69893
Update rfcs/0145-doc-strings.md
hsjobeki Mar 30, 2023
b4a1297
add: more examples, explanations
hsjobeki Mar 30, 2023
f6bd84f
Update 0145-doc-strings.md
hsjobeki Mar 30, 2023
4d2329a
Update 0145-doc-strings.md
hsjobeki Mar 30, 2023
402f065
Update rfcs/0145-doc-strings.md
hsjobeki Mar 30, 2023
fa2cb38
Update 0145-doc-strings.md
hsjobeki Mar 31, 2023
2fdb3c2
Update rfcs/0145-doc-strings.md
hsjobeki Apr 1, 2023
805a8e1
Update rfcs/0145-doc-strings.md
hsjobeki Apr 1, 2023
c9d19a6
Update rfcs/0145-doc-strings.md
hsjobeki Apr 1, 2023
83ebf36
Merge branch 'NixOS:master' into feat/doc-strings
hsjobeki Apr 2, 2023
e677af5
Restructuring
hsjobeki Apr 2, 2023
84b29fb
Update 0145-doc-strings.md
hsjobeki Apr 2, 2023
d5e3083
fix some minor grammar mistakes
hsjobeki Apr 2, 2023
6fc5a41
Consolidate into one big table
hsjobeki Apr 4, 2023
d546b39
Update 0145-doc-strings.md
hsjobeki Apr 4, 2023
9f9c5d7
Extend references
hsjobeki Apr 4, 2023
29eea3e
Update 0145-doc-strings.md
hsjobeki Apr 4, 2023
1894149
Update 0145-doc-strings.md
hsjobeki Apr 4, 2023
b511aa1
Update 0145-doc-strings.md
hsjobeki Apr 4, 2023
a9e380b
Update 0145-doc-strings.md
hsjobeki Apr 5, 2023
9ac29d9
Update 0145-doc-strings.md
hsjobeki Apr 6, 2023
1b5e5ef
Update 0145-doc-strings.md
hsjobeki Apr 6, 2023
498b045
update
hsjobeki Apr 6, 2023
6d47a93
update
hsjobeki Apr 6, 2023
14dca53
update
hsjobeki Apr 6, 2023
fe8ab29
work feedback into it
hsjobeki Apr 6, 2023
967136c
Work feedback into document
hsjobeki Apr 6, 2023
b581941
point to type checking
hsjobeki Apr 6, 2023
1f5bf5e
Update rfcs/0145-doc-strings.md
hsjobeki Apr 6, 2023
c8e85f3
Update 0145-doc-strings.md
hsjobeki Apr 7, 2023
5da22b4
Add roberth's PR from 2017
hsjobeki Apr 8, 2023
434f8b4
Update rfcs/0145-doc-strings.md
hsjobeki Apr 8, 2023
1105ea3
Update rfcs/0145-doc-strings.md
hsjobeki Apr 8, 2023
cb7f9d6
Update rfcs/0145-doc-strings.md
hsjobeki Apr 8, 2023
e5397ee
Update 0145-doc-strings.md
hsjobeki Apr 8, 2023
403b8cd
Update 0145-doc-strings.md
hsjobeki Apr 9, 2023
f7b4fb4
Add multiline doc string draft
hsjobeki Apr 9, 2023
40a51a1
add: point to the concerns
hsjobeki Apr 12, 2023
254863e
add: motivation multiline comments
hsjobeki Apr 12, 2023
acb9815
Feedback from docs-team
hsjobeki Apr 14, 2023
86475de
Update 0145-doc-strings.md
hsjobeki Apr 17, 2023
1097607
Update 0145-doc-strings.md
hsjobeki Apr 17, 2023
72b1c80
Merge pull request #3 from hsjobeki/documentation-team-feedback
hsjobeki Apr 17, 2023
b570f1c
Update 0145-doc-strings.md
hsjobeki Apr 17, 2023
48477b1
Update 0145-doc-strings.md
hsjobeki Apr 17, 2023
3c1a8f7
clearify: doc comment reference logic
hsjobeki Apr 20, 2023
834f8d4
Update rfcs/0145-doc-strings.md
hsjobeki Apr 20, 2023
e693a28
Update rfcs/0145-doc-strings.md
hsjobeki Apr 29, 2023
fc92941
Update rfcs/0145-doc-strings.md
hsjobeki Apr 29, 2023
c30cb33
Update rfcs/0145-doc-strings.md
hsjobeki Apr 29, 2023
bf9cf3c
Update rfcs/0145-doc-strings.md
hsjobeki Apr 30, 2023
caa849a
clarify & add some more examples
hsjobeki Apr 30, 2023
fcc76be
Merge branch 'feat/doc-strings' of github.com:hsjobeki/rfcs into feat…
hsjobeki Apr 30, 2023
6790f9d
Update rfcs/0145-doc-strings.md
hsjobeki Apr 30, 2023
298955f
Update rfcs/0145-doc-strings.md
hsjobeki Apr 30, 2023
477c880
Update rfcs/0145-doc-strings.md
hsjobeki Apr 30, 2023
6d4a327
Update rfcs/0145-doc-strings.md
hsjobeki Apr 30, 2023
e094210
update nixdoc format according to current nixodc-maintainer
hsjobeki Apr 30, 2023
05c3c9d
Update rfcs/0145-doc-strings.md
hsjobeki Apr 30, 2023
6ad8480
Update 0145-doc-strings.md
hsjobeki Apr 30, 2023
321fbce
Update 0145-doc-strings.md
hsjobeki Apr 30, 2023
3066a3e
Update 0145-doc-strings.md
hsjobeki Apr 30, 2023
92919d7
Update 0145-doc-strings.md
hsjobeki Apr 30, 2023
36adf87
Update 0145-doc-strings.md
hsjobeki Apr 30, 2023
cd3cf33
Update rfcs/0145-doc-strings.md
hsjobeki May 1, 2023
65d33a6
work feedback from @asymmetric in
hsjobeki May 6, 2023
56f25ca
Add @sternenseemann as sheperd
hsjobeki May 12, 2023
be8fa44
Add sheperd team members
hsjobeki Jul 31, 2023
bb33f91
Apply suggestions from @asymmetric
hsjobeki Jul 31, 2023
63321c4
Rework: improves content for problem targeting and readablity
hsjobeki Jul 31, 2023
b4067a8
Merge branch 'NixOS:master' into feat/doc-strings
hsjobeki Sep 28, 2023
f146807
Clean up RFC according to meeting notes
hsjobeki Sep 28, 2023
4c8fc55
Update 0145-doc-strings.md
hsjobeki Sep 29, 2023
273ace0
Update 0145-doc-strings.md
hsjobeki Sep 29, 2023
ba8d6f5
Update 0145-doc-strings.md
hsjobeki Sep 29, 2023
5599344
Update 0145-doc-strings.md
hsjobeki Sep 29, 2023
b986270
Update 0145-doc-strings.md
hsjobeki Sep 29, 2023
b133e65
Update 0145-doc-strings.md
hsjobeki Sep 29, 2023
f415a11
Add non goal
hsjobeki Sep 29, 2023
6864009
remove unnecessary sentence
hsjobeki Oct 26, 2023
174040a
Code has interface
hsjobeki Oct 26, 2023
b6bea69
More specific outer format
hsjobeki Oct 26, 2023
70bca5e
Single format simplifies tooling.
hsjobeki Oct 26, 2023
72359a2
fix typo
hsjobeki Oct 26, 2023
00e76a7
Typo
hsjobeki Oct 27, 2023
d829157
Correct statement about old pr
hsjobeki Oct 27, 2023
1c1eacc
Dont overspecify whitespaces
hsjobeki Oct 27, 2023
74820d5
Update rfcs/0145-doc-strings.md
hsjobeki Oct 27, 2023
fedeadf
strictly follow rfc72
hsjobeki Oct 28, 2023
4ee5636
Attribute path leafs: add example
hsjobeki Oct 29, 2023
cc333bd
Update 0145-doc-strings.md
hsjobeki Oct 29, 2023
b26faa5
Update 0145-doc-strings.md
hsjobeki Oct 30, 2023
d6c2590
Specify documentable nodes. Not only expressions
hsjobeki Oct 31, 2023
fcc24cd
Update 0145-doc-strings.md
hsjobeki Oct 31, 2023
51f5bcc
typo: partial applications
hsjobeki Nov 3, 2023
1e3f041
feedback from comment
hsjobeki Nov 4, 2023
6471c42
Add migration example
hsjobeki Nov 8, 2023
e6870a0
Add link to codemod on migration example
hsjobeki Nov 9, 2023
9dcad4a
Add non goal: Styling of markdown
hsjobeki Nov 9, 2023
4fa538f
Call implementation comments
hsjobeki Nov 9, 2023
005e34f
Update: Mental model about arguments
hsjobeki Nov 9, 2023
6c74780
Move single line comments to future work
hsjobeki Nov 9, 2023
a9dad7b
Remove partial lambda example
hsjobeki Nov 9, 2023
2987912
fix typos
hsjobeki Nov 16, 2023
e4a6dd7
nix implementation is out of scope.
hsjobeki Nov 19, 2023
90d219b
Add occurence details about /**/ and /** */
hsjobeki Nov 20, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
390 changes: 390 additions & 0 deletions rfcs/0145-doc-strings.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,390 @@
---
feature: doc-strings
hsjobeki marked this conversation as resolved.
Show resolved Hide resolved
start-date: 2023-03-27
author: hsjobeki
co-authors: (find a buddy later to help out with the RFC)
shepherd-team: (names, to be nominated and accepted by RFC steering committee)
shepherd-leader: (name to be appointed by RFC steering committee)
related-issues: (will contain links to implementation PRs)
---

# Summary
[summary]: #summary

Standard for Doc-strings

hsjobeki marked this conversation as resolved.
Show resolved Hide resolved
# Motivation
[motivation]: #motivation
hsjobeki marked this conversation as resolved.
Show resolved Hide resolved

This RFC aims at improving quality and consistency of in code documentation. (aka Doc-strings)

The community offers tools and methods to write in-code documentation for functions and other code related atomic expressions.
This functionality is currently utilized to build a subset of documentation for nix functions. (e.g. nixpkgs.lib documentation via tool: `nixdoc`)
hsjobeki marked this conversation as resolved.
Show resolved Hide resolved

However the quality and consistency of that __docs-strings__ is itself neither well documented nor standardized.

This RFC aims at achieving better quality and consistency for docs-strings. Because they carry great documentation potential and allow additional documentation improvements.

That would allow native nix support, documentation-team or community-driven solutions for automatically generating documentation from them.

This RFC is intended to be the central place where doc-strings are specified.

__Current issue__

> The existing doc-strings heavily depend on a tool called `nixdoc` and not vice versa.
>
> Instead I want to provide a common standard that every nix user can refer to.

Everything until now is just a draft if you can provide better ideas e.g. using different formats or syntax please let me know.

> This RFC aims for general rules for doc-strings.
> Features like: "what different sections exist" and if the might have complex rules (e.g. type: syntax) is not specified.
>
> This RFC aims at providing a formal skeleton, where sections can be extended by the nix community

# Detailed design
[design]: #detailed-design

The following abstract rules describe how to write doc-strings.

The rules are partially derived from the sections below where alternative solutions are considered. So make sure to read them as well.

> I'am very happy if you comment about whether we should use `## {content}` or `/** {content} */`
> I did write this RFC tailored towards `##` but using `/** */` is still an open discussion.

We must find one solution out of the following:

hsjobeki marked this conversation as resolved.
Show resolved Hide resolved
| | 0 `##` | 1 `/** */` |
|---|---|---|
| 0 `# {Keyword}` | `## # Example` | `/** # Example */` |
| 1 `@{Keyword}:` | `# @Exmaple:` |`/** @Example: */` |
hsjobeki marked this conversation as resolved.
Show resolved Hide resolved

Proposed Solution (0,0) => `##` For docstring body and markdown headings `# H1`

### Format Rules
hsjobeki marked this conversation as resolved.
Show resolved Hide resolved

- [F100] - Docs-string are all comments. That start with `##` or `#!` e.g. `## {content}`

- [F200] - Doc-strings always document / relate to an expression.
- [F201] - Doc-strings starting with `##` relate to the expression in the next line / or more precisely to the next node in the AST. (Details follow, as this might be non-trivial)
- [F202] - Doc-strings that are at the top of a file and that start with `#!` describe the expression exported from the whole file. (Previous node in AST)
hsjobeki marked this conversation as resolved.
Show resolved Hide resolved

- [F300] - The docstring is continued in the next line if it starts with `##` as well. Leading whitespace are allowed.
hsjobeki marked this conversation as resolved.
Show resolved Hide resolved

### Structural Rules

- [S010] - The content of a doc-string is Markdown.

- [S021] - Content before the first [optional] section is called `description`.

- [S022] - Headings H1 are reserved markdown headings. Which are specified in [this list](#keywords). Users are allowed to only use H2 (or higher) headings to their free use.
- [S012] - Every [optional] section started by an H1 heading is continued until the next heading starts. To the very end of the comment otherwise.
- [S014] - Every section defines its own rules while they must be compatible with the formal requirements of doc-strings (this RFC) the can override formal rules locally. (e.g. disable markdown, use custom syntax etc.)
- [S017] - Only the H1-sections (`Keywords`) described in in this RFC do exist. (See [the list](#keywords))
- [S018] - In case of extension, every new section `Keyword` must be added to this RFC first.
- [S030] - If sections follow complex logic it is embraced to specify that logic in an separate sub-RFC.
- [S040] - Usage of the described sections is totally OPTIONAL.
- ... more tbd.

## Keywords
[keywords]: #keywords

I wanted to keep the list of initial keywords short. So by the time this RFC focuses on the formal aspects of doc-strings first. More keywords and features for them can be added later on.

| Keyword | Description | Note |
| --- | --- | --- |
| `Example` | Starts the Example-block. Often contains comprehensive code examples | |
| `Type` | Start the Type-block, it is any free text | Syntax may eventually be specified in the future. [preview](https://typednix.dev). |

## Decision reasons

### Why use `##` ?

This is a quite big change to the existing documentation convention. The reason behind this: Better do it right when always being downwards compatible holds you back. We created a pro-con list in the sections below.

### Additional `#`

This provides distinction between regular comments and those who are actually doc-strings.

### Start with description

This allows for quick writing without the need for any complex block building

### Block continuation

This works like `Markdown` and allows for intuitive usage without knowledge of complex syntax rules.

### Blocks appear only once

This reduces complexity and avoids confusion if there is only one place for every concern.

### All Keywords live in this RFC

This ensures every keyword is documented.

### New Keywords

Ensures newly introduced keyword are discussed in this context first.

If they bring in more complex sub-features (like Types) those can be discussed in separate RFCs which are back-linked in the [keywords](#keywords) table. This helps to keep this overarching proposal clean and short.

# Examples and Interactions
[examples-and-interactions]: #examples-and-interactions

The following example illustrates the structure of doc-strings

- starting with `##`
- doesn't change the nix syntax

```nix
# Example - structure


## <- Description content->
## @Example:
## <- Some comprehensive code examples ->
## @Type:
## <- Type ->
```
hsjobeki marked this conversation as resolved.
Show resolved Hide resolved

Example: old docs-strings. (To be changed by this RFC)

```nix
hsjobeki marked this conversation as resolved.
Show resolved Hide resolved
# lib/attrsets.nix

/* Create a new attribute set with `value` set at the nested attribute location specified in `attrPath`.
Example:
setAttrByPath ["a" "b"] 3
=> { a = { b = 3; }; }
Type:
setAttrByPath :: [String] -> Any -> AttrSet
*/
setAttrByPath
```

Example: After changes.

```nix
# lib/attrsets.nix

## Create a new attribute set with `value` set at the nested attribute location specified in `attrPath`.
##
## # Example
hsjobeki marked this conversation as resolved.
Show resolved Hide resolved
## setAttrByPath ["a" "b"] 3
hsjobeki marked this conversation as resolved.
Show resolved Hide resolved
## => { a = { b = 3; }; }
##
## # Type
## setAttrByPath :: [String] -> Any -> AttrSet
setAttrByPath
```

## Why change the existing block specifiers?

First of all: There are no actual block specifiers within nix or nixpkgs. The existing blocks heavily depend on a tool called `nixdoc` and not vice versa.

-> See [github:nix-community/nixdoc](https://github.com/nix-community/nixdoc)

hsjobeki marked this conversation as resolved.
Show resolved Hide resolved
> `nixdoc` MUST be changed to support this RFC. (See [Future work](#future-work))

The sequence `Example:` has some drawbacks when it comes to syntax:

1. It is possible that this sequence occurs in a natural text without the intention to start a new docs-string block.
2. It doesn't visually stand out.
3. It is bad that the line needs to start with `Example:` to be valid syntax. Although it is a good practice while writing comments. This shouldn't be syntactically required. > (`nixdoc` requires it).

## Interactions

Why doc-strings are valuable

Doc-strings can be attached to AST nodes without having effect on the actual compile-, evaluation- or build-time because they are just comments. Specialized tools can handle those comments and create static documentation from them. Also integration with LSP is possible.

# Drawbacks
[drawbacks]: #drawbacks

- Changes the existing comments inside the code base.

This could mostly be automated. (e.g via codemod)

Also this affects only the `lib` folder and few other places that are currently used to build the documentation.

# Alternatives
[alternatives]: #alternatives

- By not implementing this feature, nix looses the ability for tool generated documentation.
hsjobeki marked this conversation as resolved.
Show resolved Hide resolved

- Documentation within code will remain unstable / only determined by nixdoc.

## Alternative formats

`##` inspired from rust's `///`. There is the alternative Format using `##`
hsjobeki marked this conversation as resolved.
Show resolved Hide resolved

Example:

```nix
# somefile.nix

## <Description or Tagline>
##
## # Example
##
## <Comprehensive code>
##
## # Type
##
## <Type Signature>
mapAttrs = f: s: #...
```

| Pro | Con |
|---|---|
hsjobeki marked this conversation as resolved.
Show resolved Hide resolved
| Saves vertical space | Needs Autocompletion (Language Server) to continue the next line. Hustle otherwise to start every line by hand |
| | Changes the existing convention |
| Doesn't need termination (e.g. */) | Can break when interrupted with newlines / non-docstring line beginnings |
| Easier to read / indentation is clear | Multiple comment tokens must be concatenated (Might be more complex) |
| Block continuation is more intuitive (With autocomplete properly setup) | |
| Uses less punctuations and special characters thus is visually more clear and requires less finger spread movements for reaching / and * and @ (for sections) | |
| Works nicely with Markdown content as indentation is visually more clear | Many `#` symbols might be confusing |

`/** */` In comparison arguments for using `/** */` together with `@{keyword}:` to start sections

Example:

```nix
/**
<Description or Tagline>
hsjobeki marked this conversation as resolved.
Show resolved Hide resolved

@Example:

<Comprehensive code>

@Type:

<Type Signature>
*/
mapAttrs = f: s: #...
```


| Pro | Con |
|---|---|
| Clear termination | Takes up more vertical space |
| Doesn't change the existing convention by much | doesn't visually stand out by much (just one more `*` ) |
| Mostly stays compatible with existing implementations | Multiple blocks are not concatenated. They need to be continued |
| No configuration required (LSP for autocompletion on newlines) | |
| | Indentation is not clear / more complex. e.g. The indentation of the first contentfull line is defined as 0, this is how "Noogle" currently works) LSPs could highlight this or show \| (vertical lines) |

## Candidates not considered

Javadoc style

```java
/**
* A short description
* @author Stefan Schneider
* @version 1.1
* @see https://some.url
*/
public class Product {
...
}
```

Although this has already sneaked into some nix comments. This format is not considered best practice for a variety of good reasons.

1. Starting every line with `*` creates visual conflicts with markdown bullet list also starting with `*`
hsjobeki marked this conversation as resolved.
Show resolved Hide resolved
2. Takes up more space and needs autocompletion to fill missing `*` beginnings when extended.
3. Pro: Indentation within is clear.
4. Most nix users cannot identify with java or javascript. They like predictable behavior.
5. Essentially combines the cons of both worlds.

## Alternative section headings

### Use markdown headings instead

Example:

```nix
# somefile.nix

## <Description or Tagline>
##
## # Example
##
## <Comprehensive code>
##
## # Type
##
## <Type Signature>
mapAttrs = f: s: #...
```

| Pro | Con |
|---|---|
| Markdown is simple | doesn't visually distinguish from `##` starting the doc-string |
| Using headings feels natural | Users may accidentally use those headings within natural language |
| | Markdown recommends using newlines before and after headings which takes up a lot of vertical space |

### Use custom headings instead

Example:

```nix
# somefile.nix

## <Description or Tagline>
##
## @Example:
##
## <Comprehensive code>
##
## @Type:
##
## <Type Signature>
mapAttrs = f: s: #...
```

| Pro | Con |
|---|---|
| Visually stands out | Is new syntax. Where markdown could be more intuitive. doc-strings already are markdown. So why not use markdown |
| Follows more closely the current convention | |
| Needs less vertical space | |
| doesn't need newlines, everything could be even within a single line, allowing compression (may not be needed ?) | |

# Unresolved questions
[unresolved]: #unresolved-questions

- Will `nix` itself implement native support like in rust -> `cargo doc`

- How can a tool keep the connection from where a docstring was defined and where the attribute was exposed (lib/default.nix exposes mapAttrs which is defined at lib/attrsets.nix)
- There are more complicated things.
hsjobeki marked this conversation as resolved.
Show resolved Hide resolved

-> Answer: A Tool might be able to keep track of a percentage of expressions. Sometimes it may be very hard or impossible. For that case the doc-string can offer a dedicated Keyword that allows to override the scope.

e.g.

The following is just an idea for a problem that will arise if tools try to track positions of doc-strings and the location in the nixpkgs tree. (Although this problem is not nixpkgs specific)

```nix
#untrackable.nix
/*!
This file is called somewhere that cannot be automatically tracked / is impossible to analyse statically.
The 'TreePath' override can be used by the docstring author to set a fixed path in the nixpkgs expression.
(This behavior will not be specified in this RFC)
@TreePath: pkgs.stdenv
*/
{...}:
{
# returns something
}
```

# Future work
[future]: #future-work

- When extending nixdoc and/or writing dedicated parsers the following persons can assist: [@hsjobeki]

- There is an RFC under construction, that specifies the used syntax within the `Type`-Block. It depends on this RFC, as this RFC is the groundwork to provide a standardized field where additional rules can apply. Core-Team: [@hsjobeki]

- `NixOS/nix` should implement native support for doc-strings. That way our users don't have to rely on nixpkgs or external tools. Those tools can still exist and provide more custom functionality, but it should be natively possible to document your nix expressions.

- Every existing and future tool can implement against this RFC and rely on it.
hsjobeki marked this conversation as resolved.
Show resolved Hide resolved