Skip to main content

Comments and Documentation

Sector9 supports single-line comments, multi-line block comments, and documentation comments. Ordinary comments help readers but do not participate in type checking, verification, or runtime output. Documentation comments are also source metadata: they can feed generated docs and directives such as @deprecated.

Single-Line Comments​

Use // to start a comment that extends to the end of the line:

// This is a single-line comment
let x = 42; // Inline comment after code

// Comments can span multiple lines
// by using // at the start of each line
let y = 10;

Single-line comments are the most common style for brief explanations and inline notes.

Block Comments​

Use /* */ for multi-line comments that can span any amount of text:

/* This is a block comment.
It can span multiple lines
without repeating any prefix. */

let config = {
timeout = 1000; /* milliseconds */
retries = 3;
};

Nested Block Comments​

Block comments can be nested, which is useful for commenting out code that already contains comments:

/*
Outer comment
/* Inner comment - this is valid */
Still in outer comment
*/

This nesting support means you can safely comment out entire sections of code without worrying about existing block comments breaking the syntax.

Documentation Comments​

Documentation comments are used for generating API documentation and providing IDE support. Sector9 supports two styles:

Line Documentation (///)​

Use /// for line-based documentation:

/// Calculates the factorial of n.
/// Returns 1 for n = 0.
public func factorial(n : Nat) : Nat {
if (n == 0) { 1 } else { n * factorial(n - 1) }
}

Block Documentation (/** */)​

Use /** */ for longer documentation blocks:

/**
* Transfers tokens between accounts.
*
* This function validates the sender has sufficient balance
* before executing the transfer.
*/
public func transfer(from : Principal, to : Principal, amount : Nat) : async Bool {
// implementation
}

Documentation comments should appear immediately before the declaration they document.

The @deprecated Directive​

Mark APIs as deprecated using the @deprecated directive in doc comments:

module API {
/// @deprecated Use newFunction instead
public func oldFunction() : Nat { 0 };

/// @deprecated Will be removed in v2.0
public let legacyValue = 42;

/// @deprecated Replaced by NewType
public type OldType = Nat;
}

Using deprecated items produces compiler warnings. This helps maintain backward compatibility while guiding users to newer APIs.

Comments in Verification Code​

Comments are particularly useful for explaining verification intent:

persistent actor {
var balance : Nat = 0;

// Invariant: balance never goes negative (guaranteed by Nat type)
invariant balance >= 0;

public func withdraw(amount : Nat) : async Bool
modifies balance
entry_requires amount <= balance; // Runtime guard for exported callers
requires amount <= balance; // Caller must ensure sufficient funds
ensures result == true ==> balance == old(balance) - amount;
{
if (amount > balance) {
return false; // Insufficient funds
};
balance -= amount;
true
}
}

Documenting Verification Properties​

Use comments to explain why invariants and contracts are needed:

persistent actor {
var counter : Nat = 0;
var limit : Nat = 100;

// Invariant: counter never exceeds limit
// This prevents overflow in dependent calculations
invariant counter <= limit;

// Loop invariant: i tracks our progress through the range
// sum accumulates the total, bounded by i * limit
public func sumToN(n : Nat) : async Nat
entry_requires n <= limit;
requires n <= limit;
{
var sum = 0;
var i = 0;
while (i < n) {
loop:invariant i >= 0 and i <= n;
loop:invariant sum == i * (i + 1) / 2;
i += 1;
sum += i;
};
sum
}
}

Comments in Tests​

Test files often use structured comments to document expected behavior:

// Test: Withdrawal with sufficient balance should succeed
// Expected: Verification passes (sat)

persistent actor {
var balance : Nat = 100;

public func testWithdraw() : async ()
modifies balance
{
// Precondition: balance = 100
assert balance == 100;

balance -= 50;

// Postcondition: balance = 50
assert balance == 50;
}
}

UTF-8 Support​

Comments support full UTF-8 text, including Unicode characters:

// 日本語のコメント
// Commentaire en francais
// Комментарий на русском

/* Unicode symbols: → ← ↑ ↓ ∀ ∃ ∈ ∉ */
let pi = 3; // Approximation of π

Error Handling​

Unclosed Block Comments​

Forgetting to close a block comment produces an error:

/* This comment is never closed
let x = 42;
// ERROR: unclosed comment

The error message indicates the starting position of the unclosed comment, making it easy to locate.

Malformed UTF-8​

Invalid UTF-8 sequences in comments produce an error:

// Contains invalid byte sequence: [0x80 0x81]
// ERROR: malformed UTF-8 encoding

Best Practices​

When to Use Each Style​

StyleBest For
//Brief inline notes, single-line explanations
/* */Multi-line explanations, temporarily disabling code
///Public API documentation, function descriptions
/** */Detailed API docs with multiple paragraphs

Documentation Guidelines​

  • Document all public functions and types with /// or /** */
  • Explain the "why" rather than the "what" in implementation comments
  • Use @deprecated to guide users away from obsolete APIs
  • Keep comments concise and up-to-date with code changes

Verification Comments​

  • Explain invariant purposes, not just their content
  • Document precondition requirements for callers
  • Note any non-obvious verification properties
  • Use consistent comment formatting in test files

Comments vs Runtime Code​

Ordinary comments are completely erased from runtime output. Documentation comments are not executable, but their metadata can affect compiler warnings:

persistent actor {
// This comment exists only in source
/* Block comments are also erased */
/// Documentation comments can be used by docs/warning tooling, not runtime

var x : Nat = 0; // This comment is removed at runtime
}

The compiled code contains no executable trace of comments. Use runtime:assert for checks that must execute at runtime, and use assert for proof-only checks.

Summary​

  • Use // for single-line comments extending to end of line
  • Use /* */ for block comments that can span multiple lines
  • Block comments support nesting for commenting out code sections
  • Use /// or /** */ for documentation comments on public APIs
  • The @deprecated directive marks obsolete code with compiler warnings
  • Comments support full UTF-8 text
  • Ordinary comments are ignored by verification and erased from runtime; documentation comments can carry metadata such as @deprecated
  • Document verification intent to help readers understand contracts and invariants