Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
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.
Comment on lines +11 to +12
Copy link
Member

Choose a reason for hiding this comment

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

This contradicts with what is said for constructor documentation. I think, the ## should be indented to the same column as the documented entity.

Moreover, it should be clear that a docstring starts with ## or {## (from what is said, it is not clear how to start multiline docstring).


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
to a single, continuous markdown file. Even though it is possible, we advise
against splitting markdown constructs like tables across multiple docstring.

For example:

```
## # Main header

{##
This is an example docstring with 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
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.
Copy link
Member

Choose a reason for hiding this comment

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

Does unnamed mean positional here? We code be more precise.

Suggested change
just as in code. Unnamed parameters cannot be documented.
just as in code. Unnamed (positional) parameters cannot be documented.

Copy link
Author

@wojpok wojpok Dec 16, 2025

Choose a reason for hiding this comment

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

No. It refers to arguments in point-free style. For example function let ignore x = id cannot be fully documented, because second argument comes from identity function. I will rephrase this part a little bit

Copy link
Author

Choose a reason for hiding this comment

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

Also wildcards may disqualify @param label. Function let ignore _ = id literally can't use @param label despite having 2 arguments


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
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
Comment on lines +79 to +80
Copy link
Member

Choose a reason for hiding this comment

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

Is there any reason to distinguish between them. The use the same namespace, so @type is sufficient.

Copy link

Copilot AI Dec 14, 2025

Choose a reason for hiding this comment

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

Missing space after the hyphen. Should be "- @type Name - " for consistency with other list items.

Suggested change
- `@type Name`- Builtin types and type synonyms
- `@type Name` - Builtin types and type synonyms

Copilot uses AI. Check for mistakes.
- `@parameter Name`
Copy link
Member

Choose a reason for hiding this comment

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

Is it for parameter declarations? The documentation should be more specific.

- `@method Type Name`
- `@val Name` - refers to any let statement
- `@handler Name`
Copy link
Member

Choose a reason for hiding this comment

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

Do we need a separate @handler opening marker? As effect capabilities are first class, we can use @val.

Copy link
Author

Choose a reason for hiding this comment

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

I don't really recall logic behind this. I think you are right, it can be deleted

- `@module Module`

Copy link
Member

Choose a reason for hiding this comment

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

It would be nice to see an example here.

## Guidelines

To ensure good and consistent quality, follow specified 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.
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
Copy link

Copilot AI Dec 14, 2025

Choose a reason for hiding this comment

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

Spelling error: "behavoiur" should be "behaviour" (or "behavior" in American English).

Suggested change
- When optional parameters are involved, describe default behavoiur
- When optional parameters are involved, describe default behaviour

Copilot uses AI. Check for mistakes.
explicitely.
Copy link

Copilot AI Dec 14, 2025

Choose a reason for hiding this comment

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

Spelling error: "explicitely" should be "explicitly".

Suggested change
explicitely.
explicitly.

Copilot uses AI. Check for mistakes.
- 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.
Copy link

Copilot AI Dec 14, 2025

Choose a reason for hiding this comment

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

Spelling error: "can not" should be "cannot" (one word when expressing inability).

Suggested change
- Doc lines, just as code, can not exceed width of 80 characters.
- Doc lines, just as code, cannot exceed width of 80 characters.

Copilot uses AI. Check for mistakes.

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

*Remeber, do not plagiariase!*
Copy link

Copilot AI Dec 14, 2025

Choose a reason for hiding this comment

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

Spelling error: "Remeber" should be "Remember".

Suggested change
*Remeber, do not plagiariase!*
*Remember, do not plagiariase!*

Copilot uses AI. Check for mistakes.
Copy link

Copilot AI Dec 14, 2025

Choose a reason for hiding this comment

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

Spelling error: "plagiariase" should be "plagiarize" (or "plagiarise" in British English).

Suggested change
*Remeber, do not plagiariase!*
*Remember, do not plagiarize!*

Copilot uses AI. Check for mistakes.

## Examples

### Int64

`Int64` is a builtin type, which means that the there is no declaration
Copy link

Copilot AI Dec 14, 2025

Choose a reason for hiding this comment

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

Grammatical issue: remove "the" before "there" - should be "which means that there is".

Suggested change
`Int64` is a builtin type, which means that the there is no declaration
`Int64` is a builtin type, which means that there is no declaration

Copilot uses AI. Check for mistakes.
of this type in Prelude. Fortunatelly, 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.

```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.

@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.
##}
pub let foldRighti1
{type A, ?i : Int, ~onError}
(f : (Int -> A -> A -> A))
(xs : List A) = ...
```