9. Writing docs that can't go stale

Definitions are documented with ordinary JSDoc. As in Unison, where docs are code, ucm treats the parts of a doc that name code as code: they're resolved to hashes when the definition is added, so they follow renames and updates, and examples are typechecked and run.

/**
 * The sum of the {@link square}s of some numbers.
 *
 * {@signature square}
 *
 * ```ts
 * sumSquares([1, 2, 3])
 * ```
 */
export const sumSquares = (xs: number[]): number => xs.map(square).reduce((a, b) => a + b, 0);

ucm docs lib.sumSquares shows it rendered, with the example evaluated:

The sum of the `square`s of some numbers.

`square : (x: number) => number`

```ts
sumSquares([1, 2, 3])
```

```text
⧩ 14
```

9.1 What a doc can contain

{@link square}, {@link lib.square}
a link, shown as the definition's current name (its shortest unambiguous suffix, like square)
{@link square | the square}, {@link square the square}
a link with its own text
{@linkcode square}
a link shown as code
{@signature square}
the definition's name and type
{@source square}
the definition's source, as a code block
a ```ts block
an example: typechecked and run top to bottom, every statement in order; each top-level expression's value is shown after the block (strings as their text), so steps that matter only for their effect are best written as consts. Examples can use what the definition's file imports: other definitions, packages, Node builtins, #ucm/server (server code runs in memory, as in tests). Other code blocks are just text
@param, @returns, @throws, @see, @example, @deprecated
JSDoc's block tags, rendered as a Parameters list, headed paragraphs, and a warning for @deprecated

Everything else is markdown: headings, lists, tables, emphasis.

9.2 How it stays current

Docs are metadata: they're not part of a definition's hash, so editing a doc doesn't change the code's identity.

9.3 Namespace READMEs

A definition named README in a namespace is that namespace's front page, as in Unison. A type alias carries a doc and nothing else:

/**
 * # Polls
 *
 * A live polling app. Start with {@link main}.
 */
export type README = never;

The editor shows it at the top of the namespace's page (editors).

9.4 Where docs are shown

built from 5890e54f