Invisible link to canonical for Microformats

ADR-023 Doc Comments via /** ... */


Status

Accepted

Context

Slug currently supports comments, but lacks a formal, structured, runtime-accessible documentation mechanism. An earlier proposal used ///-style line comments for documentation, but this introduced ambiguity, duplication of syntax, and complexity in parsing and tooling.

Slug emphasizes:

  • minimal surface area
  • explicit rules
  • strong guarantees over silent behavior
  • runtime introspection for tooling and REPLs

We want a documentation system that:

  • is unambiguous and strict
  • integrates naturally with existing block comments
  • supports structured extraction
  • attaches only to well-defined program elements
  • is accessible at runtime as metadata

Decision

Slug introduces C-style doc block comments using /** ... */ and removes support for /// doc comments entirely.

1. Comment Forms

Normal block comments

  • Syntax: /* ... */
  • Nestable
  • Ignored by the parser except as trivia

Doc block comments

  • Syntax: /** ... */
  • Not nestable
  • Parsed specially
  • Produce documentation metadata

Lexer behavior:

  • Upon encountering /**, the lexer enters doc comment mode
  • The first matching */ terminates the doc comment
  • Any /* or /** inside a doc comment is treated as plain text

2. Doc Block Formatting (Strict)

Inside a /** ... */ block:

  • The opening /** and closing */ lines are ignored
  • Every non-empty line must begin with optional whitespace followed by *
  • If a non-empty line does not start with *, this is a parse error

Extraction rules:

  • Strip leading whitespace
  • Remove the leading *
  • Remove one optional following space (* )
  • Preserve blank lines

This strictness prevents malformed documentation from silently degrading.

3. Attachment Rules

Doc comments attach only to top-level val, var, or foreign declarations (including any associated @tags).

Allowed between doc comment and declaration

Only the following may appear between a doc comment and the declaration it attaches to:

  1. Blank lines
  2. Top-level @tags (e.g. @export, @testWith)
  3. Other comments

Any other statement or declaration breaks attachment.

Doc comments attach to the declaration including its associated tag block.

4. Multiple Doc Comments

If multiple doc comments are stacked immediately before a declaration:

/** * First */
/** * Second */
val x = 1

The closest doc comment wins. Earlier doc comments are ignored.

5. Module Documentation

A doc comment is treated as the module doc if:

  1. It is the first meaningful item in the file (ignoring whitespace and comments)
  2. It is followed by at least one blank line before the next non-comment token

Otherwise, it is treated as a normal doc comment candidate for attachment.

6. Runtime Metadata

Documentation is stored as module metadata at load time.

Docs are recorded only for:

  • top-level val
  • top-level var
  • top-level foreign

Local bindings, closures, and dynamically created values do not carry documentation metadata.

7. slug.meta API

The following functions are added to slug.meta:

docs(value) -> string | nil

Returns the doc comment associated with a top-level val, var or foreign binding.

  • Returns nil if the value has no binding identity
  • Returns docs from the defining module for imported bindings
  • Unexported bindings may return nil depending on runtime visibility

moduleDocs(@str name) -> string | nil

Returns the module-level documentation for the named module (e.g. "slug.std"), or nil if none exists.

Consequences

Positive

  • Single, canonical doc syntax
  • Strict rules prevent silent documentation failures
  • Simple, deterministic attachment semantics
  • Runtime-accessible documentation enables:

    • REPL help
    • doc generators
    • test discovery
    • reflection tooling
  • Parser and lexer remain simple and predictable

Negative

  • Doc comments cannot be nested
  • Docs are limited to top-level declarations
  • Malformed doc blocks cause parse errors rather than being ignored

Neutral

  • Existing /// doc syntax is removed entirely
  • Documentation is a compile-time concern with runtime exposure, not a runtime construct