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:
- Blank lines
- Top-level
@tags(e.g.@export,@testWith) - 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:
- It is the first meaningful item in the file (ignoring whitespace and comments)
- 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
nilif the value has no binding identity - Returns docs from the defining module for imported bindings
- Unexported bindings may return
nildepending 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