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