Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions src/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,4 @@
- [General](conv/general.md)
- [Naming](conv/naming.md)
- [Code Formatting](conv/code-formatting.md)
- [Code Documentation](conv/documentation.md)
162 changes: 162 additions & 0 deletions src/conv/documentation.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
# Code Documentation

The standard library documentation is written in a "code-first" style. This
means all necessary comments and descriptions are embedded directly in the
code, and a specialized tool generates the appropriate documentation pages
from the code.

## Documentation format

Documentation comments—also referred to as docstrings—can be either single-line
or multi-line. They always begin with a double `##` symbol and must start in
the first column of an empty line.

The body of the docstring supports Markdown formatting. Markdown headers are
usually written using single-line comments. The body of a block docstring is
either written inline or starts on the next line, indented with 2 spaces. The
closing marker of a multiline comment can appear either on a separate line or
immediately after the final line of the docstring body.

During the process of generting doc pages, all docstring are concatenated
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
During the process of generting doc pages, all docstring are concatenated
During the process of generating doc pages, all docstring are concatenated

to a single, continuous markdown file. Even though it is possible, we advise
against splitting markdown constructs like tables across multiple docstring.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
against splitting markdown constructs like tables across multiple docstring.
against splitting markdown constructs like tables across multiple docstrings.


For example:

```
## # Main header

{##
This is an example docstring with markdown table:
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
This is an example docstring with markdown table:
This is an example docstring with a markdown table:


| Column 1 | Column 2 |
| -------- | -------- |
| 10 | abc |
| 20 | def |

End of docstring.
##}

{##
Another docstring with inlined closing sign. ##}

{## This is valid too. ##}
```

### Definition documentation

When a docstring is immediately followed by a code definition, it is attached
to that definition. The first continuous block of text is treated as a brief
description. After an empty line, a more detailed explanation may be added.

Additionally `@param`, `@asserts` and `@return` labels are supported in

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Additionally `@param`, `@asserts` and `@return` labels are supported in
Additionally, `@param`, `@asserts`, and `@return` labels are supported in

We use Oxford commas everywhere in dbl comments, so let's keep things consistent

functions' and methods' docstrings. These must be placed after the brief
description.

The `@param` label is followed by a parameter name and may include an optional
description. Optional and implicit parameters must be prefixed with `~` or `?`,
just as in code. Unnamed parameters cannot be documented.

The `@asserts` label indicates that the function may raise a runtime error and
terminate program execution. You may add a description explaining under what
conditions this occurs.

The `@returns` label describes the result produced by the function.

### Scopes

Sometimes, the natural flow of documentation is disrupted—such as when type
definitions, methods, or helper functions are declared elsewhere for structural
or organizational reasons. In such cases, attaching a docstring directly above
the definition isn't possible or desirable. To address this, documentation can
be written separately and explicitly linked to the intended code element using
an identifier.

In such cases, docstrings are mandatorily multiline and apropriete identifiers
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
In such cases, docstrings are mandatorily multiline and apropriete identifiers
In such cases, docstrings are mandatorily multiline and apropriate identifiers

are written in the same line as the comments' opening markers.

Supported identifiers include:
- `@data Name` - ADTs and records
- `@type Name`- Builtin types and type synonyms
- `@parameter Name`
- `@method Type Name`
- `@val Name` - refers to any let statement
- `@handler Name`
- `@module Module`

## Guidelines

To ensure good and consistent quality, follow specified these guidelines:

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
To ensure good and consistent quality, follow specified these guidelines:
To ensure good and consistent quality, follow these guidelines:


- Less is more - avoid long descriptions.
- Sentences should be written in Present Simple tense,
although sometimes it is necessary to deviate from that.
- End every sentence with a period.
- Avoid using function name as noun and verb in the same sentence.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- Avoid using function name as noun and verb in the same sentence.
- Avoid using the function name as a noun and a verb in the same sentence.

Specifically don't write descriptions like "`map` maps ..." and

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Specifically don't write descriptions like "`map` maps ..." and
Specifically, don't write descriptions like "`map` maps ..." and

"`append` appends ...".
- Do not use code in brief descriptions to explain behaviour of a function.
- When optional parameters are involved, describe default behavoiur
explicitely.
- Document edge cases of a function.
- Do not document types of a function and arguments, unless necessary. All type
annotations
will be added by a documentation tool.
- Doc lines, just as code, can not exceed width of 80 characters.

When in doubt, feel free to lookup examples of other languages' documentation.

*Remeber, do not plagiariase!*

## Examples

### Int64

`Int64` is a builtin type, which means that the there is no declaration
of this type in Prelude. Fortunatelly, scoping allows us to add docstring
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
of this type in Prelude. Fortunatelly, scoping allows us to add docstring
of this type in Prelude. Fortunately, scoping allows us to add docstring

regardless.

```fram
## ## Int64

{## @type Int64

A builtin type, representing native, signed 64bit integers.
##}

{##
64bit integer division.

@asserts Divisor cannot be equal to 0.
##}
pub method div (self : Int64) = ....
```

### foldRighti1

Imagine a `foldRight` variant that takes last element as an accumulator.
If applied to empty list, it calls implicit function `~onError`.
It also allows overriding the starting value of the iterator index `i`.

Even though, the type is quite ellaborate, documentation is straightforward.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Even though, the type is quite ellaborate, documentation is straightforward.
Even though, the type is quite elaborate, documentation is straightforward.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Even though, the type is quite ellaborate, documentation is straightforward.
Even though the type is quite elaborate, documentation is straightforward.


```fram
{##
Folds list into a single value, using the last element of list as the initial
accumulator and passing index of each processed element.

Allows overriding initial value of iterator. When applied
to empty list, calls implicit `~onError` function.
Comment on lines +145 to +149

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Folds list into a single value, using the last element of list as the initial
accumulator and passing index of each processed element.
Allows overriding initial value of iterator. When applied
to empty list, calls implicit `~onError` function.
Folds the list into a single value, using the last element of list as the initial
accumulator and passing index of each processed element.
Allows overriding the initial value of the iterator. When applied
to an empty list, calls implicit `~onError` function.


@param ?i Initial value of the iterator index. Defaults to 0.
@param ~onError Fallback function for an empty list.
@param f Folding function. Receives an additional index argument.
@param xs List to be folded.

@returns The result of iterativately applied folding operation.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
@returns The result of iterativately applied folding operation.
@returns The result of the iteratively applied folding operation.

##}
pub let foldRighti1
{type A, ?i : Int, ~onError}
(f : (Int -> A -> A -> A))
(xs : List A) = ...
```