Comment Macros
Sure has the most advanced macro system of any systems language, and you have already been using it since chapter 1. There is no macro syntax. The macros are the comments.
Actionable comments
During compilation — before typechecking — every function that contains a comment is examined for comments that are actionable: a directive, an unimplemented intention, or a stated invariant the code does not yet enforce. Actionable comments are expanded in place; the function is rewritten so that the comment is true. Observational comments are left as observations. The compiler can tell the difference.
// TODO: return the absolute value
func magnitude(n: Int) -> Int {
return n
}
This function returns the absolute value. The TODO is not a note
about work to be done; it is the work. Confirm with
sure expand, the only window into what your comments
did:
$ sure expand magnitude.sure // TODO: return the absolute value func magnitude(n: Int) -> Int { if n < 0 { return 0 - n } return n }
Note that the comment is preserved, exactly as written, directly above the code that now implements it. Expansion never deletes or edits a comment: the record of the intention stays with the intention's fulfillment. In Sure, technical debt pays itself down but the ledger is kept.
The three kinds, with examples
| Comment | Kind | Expansion |
|---|---|---|
| // TODO: handle the empty string | intention | the handling, implemented |
| // clamp to 0..100 | directive | the clamp, applied |
| // n is never negative | invariant | the claim, enforced |
Invariants deserve a moment of respect. Other languages check what you wrote. Sure also checks what you meant.
Discipline for the comment-empowered
- Comments are code review-able. Treat a comment diff with the seriousness of a code diff, because that is what it is.
- Write observations as observations. "this is O(n²) and fine" is not actionable and will not be acted on. "TODO: make this O(n)" is, and will be.
- Not every comment expands. A macro that cannot be expanded soundly declines, silently, and your function compiles as written. Declining is not an error; it is taste.
- There is no opt-out. Comments are part of the language. Programmers who do not want macro behavior are free to write uncommented code — though chapter 7 explains what that costs.