| # Documentation Style Guide | |
| This is a style guide for Lean documentation. Please use it for all | |
| documentation that’s officially provided by the project, where | |
| authorship and responsibility are attributed to the project as a | |
| whole. Existing documentation should be brought progressively more in | |
| line with this style, rather than less, as it’s edited, but changes to | |
| code that require documentation changes for correctness do not | |
| necessarily require style updates at the same time. Maintaining | |
| internal consistency in a page or document is more important than | |
| updating one subsection of it to match these guidelines. | |
| Individuals writing texts where they are named as the author do not | |
| need to follow all of these guidelines. It’s good to maintain internal | |
| consistency, but a book or blog post with a named author may use a | |
| different standard (e.g. British, Indian, or Canadian English) or | |
| adopt a register that is more or less formal than that which we use | |
| for reference materials or official tutorials. | |
| This guide is based on advice provided in the Chicago Manual of Style, | |
| 18th Edition, the [MDN style guide](https://developer.mozilla.org/en-US/docs/MDN/Writing_guidelines/Writing_style_guide), | |
| the [Rust API documentation style guide](https://github.com/rust-lang/rfcs/blob/master/text/1574-more-api-documentation-conventions.md#appendix-a-full-conventions-text), | |
| and to a lesser extent the [Google](https://developers.google.com/style) | |
| and [Microsoft](https://learn.microsoft.com/en-us/style-guide/welcome/) | |
| style guides. If something isn’t mentioned here, use these resources in | |
| that order for guidance (and consider updating this document). | |
| The most important principles are: | |
| * Be clear and consistent. Remove ambiguity when possible, use the | |
| same technical terms for the same concepts everywhere, and work | |
| towards a consistent register within any given class of documents. | |
| * Write according to the context in which the information will be | |
| consumed. Text intended for quick reference in hover popups in text | |
| editors should be written differently than text intended to be | |
| consulted in a larger browser window, though the former can be | |
| effectively used as part of the latter. | |
| * Be accessible to our most important target audiences. In order, this | |
| is: software developers and mathematicians who are learning Lean but | |
| have not used related tools before, current Lean users with | |
| backgrounds in mathematics or programming, and experts with | |
| backgrounds in related tools who are learning Lean. | |
| ## General Rules | |
| These overall principles apply to all Lean documentation, including | |
| docstrings, the reference manual, the developer’s guide, and | |
| examples. Their purpose is to give a common and consistent “voice” to | |
| the documentation, to help writers with varied linguistic, academic, | |
| and cultural backgrounds work together productively, and to help make | |
| sure we take our whole intended audience into account. | |
| Many of these guidelines are essentially arbitrary. There’s no | |
| fundamental reason to choose US English over another written standard, | |
| nor to choose the *Chicago Manual of Style* as a default arbiter of | |
| disputes. Like a standardized coding style, it’s more important to | |
| *have* a broadly acceptable standard than to customize the one that | |
| fits any particular taste, and spending time debating which | |
| punctuation or spelling standard to adopt takes time away from | |
| actually writing documentation. | |
| Other guidelines come from our practical experiences in a diverse | |
| community. Even though we use US English, we should avoid Americanisms | |
| that are not widely understood internationally. By identifying and | |
| avoiding specific language usage that is popular among research | |
| mathematicians or software developers, but not common to both, we can | |
| write texts that are useful to as many readers as possible. | |
| ### Readers First | |
| If adherence to one of the rules described here would make the text | |
| more difficult to understand, and there’s no clear way to rewrite the | |
| text to be both consistent and comprehensible, then the rule should be | |
| broken. If you are writing with a tool that supports it, leave a | |
| comment that documents this decision. | |
| ### Audience | |
| All texts should be written for a particular audience. For most Lean | |
| documentation, this audience consists of mathematicians, working | |
| software developers, computer scientists, and students learning these | |
| fields. The audience consists of readers with many first languages and | |
| cultural backgrounds. Texts should be as accessible as possible to | |
| these readers, and generally not assume that they’ve completed a | |
| standard undergraduate mathematics or computer science curriculum, | |
| though it’s acceptable to assume knowledge that is common to both but | |
| not shared by the general public. As an exception to this principle, | |
| it’s usually also acceptable to assume familiarity with functional | |
| programming concepts such as monads. | |
| It is not always feasible to make all text accessible to all | |
| readers. If part of the documentation is specific to programming | |
| applications, or is necessary for experts in a particular sub-field, | |
| try to place it in an independent section. This allows the readers who | |
| can benefit from it to do so, while others can more easily skip it. | |
| It’s acceptable to write documentation that assumes a different | |
| audience. For example, tutorials may assume even less background | |
| knowledge of logic and mathematics, while documentation that describes | |
| how to build custom proof automation can assume more knowledge of | |
| functional programming and Lean’s type theory. When a document has a | |
| non-default audience, please document this explicitly. | |
| ### US English, Chicago Style | |
| There are multiple codified written standards for English. We use US | |
| English spelling and grammar, and unless otherwise specified, we | |
| follow the *Chicago Manual of Style*, 18th Edition, Part II. We use | |
| *Chicago* to resolve conflicts or disagreements about style, but | |
| there’s no need to memorize it. Specific points to be aware of, or | |
| explicitly-chosen deviations from it, will be summarized in this | |
| document as necessary. | |
| There’s no need to precisely adhere to *Chicago* for citations of | |
| academic publications. Please choose any format that readers will | |
| understand and that appropriately credits the work. In formats that | |
| use inline citations, prefer author-year styles over numbered styles. | |
| ### Conservative Usage | |
| Outside of technical terminology, avoid words that are not well | |
| established. When the meaning of a word has changed recently or is in | |
| the process of changing (such as “literally”), or when it has | |
| different meanings to different language communities, choose a | |
| different word. | |
| If new terminology is needed, choose established terminology from | |
| mathematics, computer science, and other formal reasoning tools. Don’t | |
| adopt existing terminology with a slightly different meaning. | |
| Avoid figures of speech that may not be understood globally, like | |
| quotes from literature, even if they make a point very well. Many | |
| members of our audience do not have English as a first language and | |
| are not familiar with US or European culture. | |
| Some fake grammar rules may be ignored. To split infinitives is | |
| perfectly acceptable in English. And it’s OK to start a sentence with | |
| a conjunction if that has the right impact. But do consider alternate | |
| formulations that won’t annoy some readers. | |
| ### Picky Usage | |
| There are certain distinctions that should be maintained in the text, | |
| but that we should not expect readers to know. Use the correct term in | |
| the correct context, but never contrast the two; the text should make | |
| sense if both were replaced by the same term. An important part of our | |
| audience will be bothered if we get these wrong, and another part has | |
| no idea that the distinction even exists. | |
| * *Parameters* are variables bound in a declaration, while *arguments* | |
| are the values actually provided at a use site. In a recursive | |
| function definition, the parameters are listed in the signature, | |
| while recursive call sites may use some of those parameters as | |
| arguments. | |
| * The *codomain* of a function is its return type, while the *range* | |
| is the set of values in that type that the function actually | |
| returns. Use *image* when talking about those values returned for | |
| some subset of the domain. | |
| * *Functions* are actually functions - not all constants in Lean are | |
| functions. Call them “defined constants” if they’re not necessarily | |
| functions. | |
| ### Quotation and Punctuation | |
| US English requires that commas and periods be inside quotation | |
| marks. Follow this rule unless it might lead to confusion, in which | |
| case the punctuation may be moved outside the quotation marks. This is | |
| particularly relevant when quoting code. | |
| ### Passive Voice | |
| Prefer the active voice, but don’t jump through hoops to avoid the | |
| passive voice. Be consistent in a given passage. | |
| ### Avoid Overly Academic Writing | |
| Write in a style that’s also accessible to those without academic | |
| training. Consider whether there’s a way to say what you want to say | |
| that uses a more widely-accessible register of English. | |
| Avoid unnecessary Latin, but use it when there’s not a good non-Latin | |
| alternative. It’s fine to use Latin loanwords that are established in | |
| English (like “establish”) - these are not Latin words anymore. Avoid | |
| phrases such as *ceteris paribus*, *viz.*, *ergo*, and *desideratum*, | |
| as well as Latin abbreviations that are not common in both US and | |
| international English. In particular, *N.B.* and *cf.* are only widely | |
| used and understood in some regions and should be avoided. Generally, | |
| *N.B.* should just be deleted, with facts stated directly, and *cf.* | |
| should be replaced with a phrase like “see …” or “this is similar to | |
| ….” | |
| The following Latin phrases and abbreviations are acceptable and | |
| should not be italicized: | |
| * ad hoc | |
| * per se | |
| * etc (but not “et cetera” or “&c”) | |
| * vice versa | |
| Domain-specific terms such as *modus ponens*, *modus tollens*, and *ex | |
| falso quodlibet* are also acceptable, but prefer “excluded middle” | |
| over “tertium non datur.” The abbreviations “i.e.” and “e.g.” should | |
| be used only at the start of a parenthetical aside (i.e. like this), | |
| and “et al.” only in the author list in a citation of an academic | |
| work. | |
| Avoid “iff”: write “if and only if” or “is logically equivalent to” | |
| instead. Readers who do not know the abbreviation may assume it is a | |
| typo. Don’t use “just in case” to mean “if and only if”. | |
| Avoid non-standard grammatical constructions and turns of phrase that | |
| primarily exist in research papers, such as “allows to” (without a | |
| direct object that says who is allowed to do something). Instead of | |
| “This system allows to generate faster code”, write something like | |
| “This system makes it possible to generate faster code.” It’s even | |
| better to be more specific in the causal relationship, like “The | |
| compact intermediate representation consumes less cache, so the | |
| resulting code runs faster.” | |
| ### Examples and Explanations | |
| Documentation should both explain the rules that apply in a given | |
| situation and provide concrete examples that illustrate the | |
| rules. Examples are not a substitute for explanations, and readers | |
| shouldn’t have to generalize themselves. At the same time, | |
| explanations without examples can be very difficult to | |
| understand. When writing, know which one you’re writing at any given | |
| time. | |
| Try to use meaningful examples when possible; it’s better to have a | |
| list of strings as input than a list of metavariables. Toy examples | |
| are fine, but they should hint at something actually useful. Avoid | |
| allusions to classical literature, popular culture, politics, or | |
| mathematical in-jokes in examples. It’s OK to have an answer be 42, | |
| but don’t pair that with something about mice that readers who are not | |
| familiar with Douglas Adams might be flummoxed by. If a classical | |
| example would help a part of the audience, then use it, but insert a | |
| brief explanation. Instead of “foo”, “bar”, and “baz”, use something | |
| like color names or the days of the week. | |
| ### Readers Determine Difficulty | |
| Don’t state to readers that something is easy—for many, it won’t | |
| be. Don’t tell them that they already know something (but it’s good to | |
| cross-reference a prior explanation). | |
| In mathematical writing, it is common to signpost statements that | |
| should be easy to indicate that readers should backtrack if this is | |
| not the case. This convention can come across as patronizing or | |
| insulting to readers who are not formally trained in math. | |
| ### Typographical Unicode | |
| The advice in this section should be adapted as appropriate to the | |
| tool being used to prepare the documentation. | |
| Use typographical Unicode where appropriate. Quotations should use | |
| left and right double or single quotes (e.g. “this” and ‘that’) rather | |
| than ASCII vertical quotes or LaTeX-style backtick quotes, and double | |
| quotes should be used for the outermost level. For example, it’s | |
| correct to nest them like this: “‘Quotation’ can’t be spelled without | |
| ‘Q’.” Use em dashes to delimit parenthetical remarks, and don’t put | |
| spaces around them—this sentence is itself an example of this | |
| style. Use en dashes for numeric or date ranges. Don’t represent en or | |
| em dashes with doubled or tripled hyphens. Use right single quotation | |
| marks for apostrophes (here’s an example) rather than ASCII single | |
| quotes. | |
| Only use ellipses in contexts where symbolic formulae would make sense | |
| (e.g. 1+2+…+n). Use a Unicode ellipsis for this purpose, rather than | |
| three periods. | |
| ### Proper Theorem Names | |
| Named theorems and axioms are proper names and are capitalized as | |
| such. Write “Axiom of Choice”, “Fermat’s Last Theorem”, “Excluded | |
| Middle”, and “Yoneda Lemma”. Numbered theorems are not names; write | |
| “see theorem 5.3”. | |
| ### Trademarks, Software Names, and Human Names | |
| Capitalize trademarks according to the owner’s wishes. If needed, | |
| rewrite a sentence to avoid a lowercase trademark name (e.g. “iOS”) at | |
| the beginning. Software systems should be capitalized as preferred by | |
| the project (e.g. “JavaScript”, “Wasm”, “Lean”). Don’t write system names in | |
| small caps. Prefer conventions chosen by the creator of an idea unless | |
| there’s a good reason not to. If no guidance is provided, follow the | |
| usual English conventions for proper names. | |
| Capitalize human names according to the wishes of the human in | |
| question. Adjectives derived from human names, such as “Abelian” and | |
| “Boolean”, should also be capitalized. | |
| As an exception to the rules for proper names, don’t capitalize “web” | |
| when used in the sense of “World Wide Web,” except as part of that | |
| particular phrase. Write “web content,” “web technologies,” or “on the | |
| web” instead of “Web content,” “Web technologies,” or “on the Web.” | |
| ### Contractions | |
| Established contractions such as “can’t” are permitted but not | |
| mandatory. Be consistent with the surrounding text and think about the | |
| general formality of the register in which it is written. | |
| ### Plurals | |
| Use English plurals for loanwords, rather than those of the lending | |
| language: “lemmas” instead of “lemmata”, “syllabuses” instead of | |
| “syllabi”, and “emojis” instead of “emoji”. | |
| ### Inline Code | |
| Treat identifiers and short snippets as if they were words. Do not | |
| change their capitalization. If the first character of a code snippet | |
| is not a capital letter, avoid using it at the start of a sentence; if | |
| this can’t be reasonably avoided, do not capitalize it. It’s perfectly | |
| fine to refer to functions or type constructors by name; there’s no | |
| need to write `f x` or `List α` to refer to `f` or `List` independent of | |
| any particular parameter. | |
| ### Code Blocks | |
| Multi-line code samples should be in a suitable block-level | |
| form. Depending on the format used to author the documentation, they | |
| may be: | |
| * “Displayed” as part of a paragraph (analogous to `displaymath` in | |
| LaTeX), in which case they should be treated as if they were a | |
| sentence. The preceding sentence should be a grammatically complete | |
| sentence, and it may end with a colon to indicate its relationship | |
| to the code block. In systems such as Markdown that don’t permit | |
| paragraphs to contain code blocks, “displayed” code should be | |
| typeset as its own block, with the preceding sentence indicating | |
| that the code is logically part of the paragraph. | |
| * In a figure, numbered listing, or other similar environment, in | |
| which case they should be referred to from the text by a number or | |
| other indicator. | |
| * Paragraph-level content in their own right, which is typically used | |
| for longer and more involved code examples. | |
| A single sentence should not include a multi-line code example the way | |
| that it may include a short snippet or identifier. | |
| ### Avoid Lean-Specific Confusion | |
| When a common English term overlaps with a technical term for Lean, | |
| don’t use it. Here are phrases to avoid, or at least carefully | |
| consider: | |
| * “for instance” (clashes with “instance of a type class”) | |
| * “class” (in the usual sense of a collection) | |
| * “list” (when not referring to a lean `List`) | |
| * “derive” (when not referring to the `deriving` mechanism) | |
| Also, try to avoid metaphorical use of mathematical concepts, because | |
| it might be unclear that the mathematical concept is not *really* | |
| being invoked. Don’t refer to things as sets or functions informally | |
| unless it’s very important. It’s perfectly acceptable to use | |
| mathematical concepts for their precise meanings; in “The priority of | |
| an instance is a function of its declared priority and its declaration | |
| order relative to other instances,” the term “function” expresses a | |
| formal specification for the system, and is being used with its usual | |
| mathematical meaning. Avoid using these terms humorously, imprecisely, | |
| or superfluously, however. Examples to avoid include: | |
| * “The set of all possible user interactions makes up Lean’s user | |
| interface.” Here, “set” does not contribute meaning and risks being | |
| a red herring. | |
| * “Hash tables are functions from keys to values.” This is almost | |
| true, if extra details are added (it’s only a partial function, for | |
| instance, and it has additional observable structure such as bucket | |
| sizes). Without this precision, it’s unclear to readers when a | |
| precise specification is being provided. | |
| * “It's a theorem that cats are better than dogs.” Here, “theorem” is | |
| used ironically to express that the speaker believes the statement, | |
| but it doesn’t express that there's an axiomatic pet system within | |
| which the statement has been derived. | |
| ### Carefully Quarantine Foundations and Metatheory | |
| Unless it’s necessary to understand the practical functioning of Lean, | |
| avoid discussion of foundational issues outside of specific materials | |
| dedicated to this topic. For most users, it’s irrelevant. When | |
| foundations are relevant to practice, it’s often for a reason that is | |
| easier to understand. For example, decision procedures that use | |
| excluded middle are less useful because excluded middle isn’t | |
| computable, which is easier to understand than a discussion of | |
| classical vs constructive logic. Users who care about foundations can | |
| refer to specific sections. Don’t “apologize” for being insufficiently | |
| constructive: either it has practical impact, in which case the | |
| tradeoffs are what’s relevant, or it doesn’t, in which case it can be | |
| ignored. | |
| ### Write From a Classical Perspective | |
| Prefer to talk about a proposition as being true or false. Prefer the | |
| conventions of mainstream mathematics, computer science, and analytic | |
| philosophy over those of intuitionistic mathematics, type theory, and | |
| programming languages. There’s nothing wrong with those fields, but we | |
| want our text to have as broad an appeal as possible and they’re a | |
| minority. | |
| ### Use Paragraphs Deliberately | |
| Each paragraph should contain related sentences. When writing in a | |
| format that makes it possible, think about the boundaries of logical | |
| paragraphs and indicate them accordingly, even in the presence of | |
| bulleted or numbered lists and “display-mode” mathematics or | |
| code. This is possible in Verso using the `paragraph` directive and in | |
| LaTeX by omitting a blank line, but it is impossible in Markdown. | |
| ### Pronouns | |
| Generally speaking, use “I” or “we” to refer to the author, authors, | |
| or provider of the documentation, if necessary. Explicitly mentioning | |
| the party in question is often clearer (e.g. “the Lean FRO” or “the | |
| Lean developers” rather than “we”). | |
| In reference documentation, running examples are typically short | |
| enough that the conversational “mathematical ‘we’” is not | |
| well-suited. In tutorials or other documentation with longer-running | |
| examples, the “mathematical ‘we’” can be used so long as it never | |
| denotes the authors in the same document. | |
| “We” should never refer to the Lean community as a whole in | |
| documentation, nor the authors of the standard library. Don’t write | |
| “We make the search efficient by globulating the hypotheses”; instead, | |
| write “Globulating the hypotheses prior to the search makes it | |
| efficient.” Prefer the passive voice to potentially ambiguous uses of | |
| “we”. In many cases, the imperative mood is useful here - “We use X | |
| for Y” can be “Use X for Y”. | |
| Use “you” to refer to the reader, rather than abstractions like “the | |
| reader”, but consider whether the fact being described is indeed one | |
| in which the reader is a participant. “The user” is particularly prone | |
| to misunderstanding, because it can be difficult to tell if the user | |
| in question is the person using Lean to build a tool or the person | |
| using the tool that was built in Lean. | |
| The pronoun “they” can be used either to refer to a group of people or | |
| to an individual of indeterminate or unknown gender. Prefer “they” | |
| over “he or she” or “(s)he.” It’s often even better to rewrite the | |
| sentence to remove the need for a pronoun, because the resulting | |
| sentence is often more clear. | |
| ### Notes (Footnotes and Marginal Notes) | |
| Notes that fall outside of the text flow, such as footnotes or | |
| marginal notes, may be used for remarks that are important for some | |
| readers but would distract from the flow of the text. Don’t put key | |
| information in notes, and write the text on the assumption that | |
| they’ll be skipped. Don’t overuse notes. | |
| For web content, prefer marginal notes or collapsing notes over | |
| footnotes that link to the bottom of the page. If the platform | |
| supports notes, use them for complete citations of works, rather than | |
| linking to a separate bibliography, so readers who are familiar with | |
| the literature can tell at a glance if the reference is what they | |
| expect. | |
| ## API Reference Documentation (Docstrings) | |
| This section describes conventions for API reference material that’s | |
| extracted from source files. This includes documentation comments for | |
| defined constants, inductive types, and axioms, along with syntax | |
| categories, syntax rules, and parsers. Essentially, if a documentation | |
| comment might appear in a hover, these conventions should | |
| apply. Module docstrings are outside the scope of this section. | |
| ### Goals | |
| **There should be a consistent user experience with respect to | |
| documentation.** Documentation should be structured in a predictable | |
| manner. Lean users should be able to find relevant information without | |
| needing to guess where to look first. The documentation should be | |
| written in a consistent style and voice. Technical terminology and | |
| jargon should be internally consistent even when there are multiple | |
| competing traditions. | |
| **In-source documentation should take its viewing contexts into | |
| account.** Docstrings are primarily viewed in editor hovers, as part | |
| of search results in tools like `doc-gen` or Loogle, and in the | |
| reference manual (in this order of importance). They should be | |
| suitable to all these contexts. They are not primarily viewed in the | |
| context of the source module in which they are defined, but they are | |
| always viewed together with the corresponding signature. | |
| **Documentation should be written in a register of English that is as | |
| accessible as possible to those who are not yet Lean users**, whether | |
| they are mathematicians or software developers. Sentences should be | |
| short and jargon should be carefully considered. | |
| **Lean should be self-contained.** Avoid linking to sources outside of | |
| the Lean repository or the reference manual. If a concept needs | |
| explaining, explain it in the reference manual and link there. Don’t | |
| explain any feature solely by reference to other systems—credit them | |
| for their innovations, but explain it from scratch too. Learning | |
| another system should not be a prerequisite for learning | |
| Lean. Exceptions may be made for standard references that have a long | |
| history of stability, when these are used to explain one of the | |
| following topics: | |
| * mathematical concepts that are out of scope for explanation in the | |
| language reference and for which understanding is not required for | |
| effective use of Lean, such as Wikipedia articles about specific | |
| axioms | |
| * specific industry-wide standards or definitions implemented by Lean, | |
| such as parts of the Unicode standard or IETF RFCs | |
| **Use structured documentation information**. Use attributes like | |
| `tactic_alias` and commands like `recommended_spelling` instead of | |
| ad-hoc text. This helps maintain consistency. | |
| **Conventions should facilitate an automated migration from Markdown | |
| to Verso.** Using Verso in docstrings will make it possible to check | |
| for out-of-date cross-references, to have machine-checked examples, | |
| and for documentation structures (e.g. new kinds of checked examples) | |
| to be defined. | |
| ### Non-Goals | |
| Docstrings do not exist to document the details or internals of the | |
| implementation for other developers. This purpose should be served by | |
| ordinary comments. | |
| ### General Conventions | |
| * Docstrings should not refer to the surrounding context of the module | |
| in which they’re defined. Avoid phrases like “`This can be seen in | |
| `otherFunction`, defined above`” and “`this module's other | |
| functions`”. | |
| * Docstrings may assume that parameter names in the corresponding | |
| signature are in scope. They may be referred to by | |
| name. Specifically, any name in the signature that can be used as a | |
| named argument at a call site may be referred to by name in the | |
| docstring; this includes names that are “after the colon.” | |
| * Docstrings should not assume that the body of the definition, the | |
| constructors of the inductive type, or the fields of the structure | |
| are visible. They should each make sense in a hover. | |
| * Prefer independently-useful documentation over cross-referencing | |
| when inheritance doesn’t make sense. This is because following | |
| cross-references is difficult in many contexts, such as editor | |
| hovers. It’s useful to relate an operation to existing ones, but the | |
| description should also stand alone. Instead of “`Variant of `f` | |
| that also receives the index`”, write a standalone description. The | |
| relationship to the other function is an additional comment that’s | |
| useful to include. | |
| * When a concept is used in multiple places, centralize its | |
| description in the reference manual rather than in one of these | |
| places. | |
| * When possible, accurately annotate code samples with their syntactic | |
| category and role. Until this is possible, try to prefix or suffix | |
| tactic names with `tactic` to help tools disambiguate. | |
| * There’s no need to say what kind of declaration is being documented | |
| in the docstring. | |
| ### Layout and Indentation | |
| Format the docstrings as follows: | |
| * The `/--` should be at the same column as the start of the | |
| declaration or constructor being documented. | |
| * If the docstring fits within the line length limit, it may be on one | |
| line that begins with `/--` and ends with `-/`. | |
| * If it does not fit within the length limit, then the `/--` and `-/` | |
| should each be on their own line. This is also acceptable if the | |
| docstring could have fit on one line. The contents should be | |
| indented to the same level as `/--` (or more if demanded by Markdown | |
| syntax) and lines should break at the column limit. Don’t use a | |
| one-sentence-per-line or a one-grammatical-clause-per-line | |
| formatting. Rewrap in VS Code is useful for this. | |
| * Use exactly one blank line between paragraphs. | |
| ### Reference Manual | |
| Docstrings can link to the reference manual using the special | |
| `lean-manual://` URL scheme. `lean-manual://section/TAG` links to the | |
| section with tag `TAG`. Tags can be found in the URL on the permalink | |
| indicator in the manual (`🔗`). | |
| ### Structure | |
| Docstrings are grouped into the following categories: | |
| * Theorems and Axioms | |
| * Declarations of new propositions or predicates, whether as inductive | |
| types, structures, or definitions | |
| * Other constants, such as definitions, axioms, opaque constants, and | |
| instances | |
| * Inductive type declarations | |
| * Structure declarations | |
| * Type classes | |
| * Syntax | |
| * Tactics or conv tactics | |
| Docstrings should note any special notation used for the name being documented. | |
| #### Theorems and Axioms | |
| Docstrings for theorems should be the theorem statement in | |
| English. Not all theorems need docstrings—they should be used for | |
| major theorems. | |
| Docstrings for axioms should begin with common names by which the | |
| axiom is known, followed by the statement in English. They may | |
| additionally elaborate on consequences of the axiom or special | |
| treatment it receives from Lean, but should do so briefly, and link to | |
| further documentation sources for details. | |
| In docstrings for both theorems and axioms, try to formulate the | |
| English-language statement with limited symbols and metavariables. Two | |
| separate presentations (the signature and the docstring) are more | |
| likely to be useful to diverse readers than a transcription of the | |
| symbols from the statement. Remember that our audience includes both | |
| software developers and mathematicians. | |
| ##### Examples | |
| ``` | |
| /-- | |
| Equality is symmetric: if `a = b` then `b = a`. | |
| -/ | |
| @[symm] theorem Eq.symm {α : Sort u} {a b : α} (h : Eq a b) : Eq b a := | |
| h ▸ rfl | |
| /-- | |
| Propositional inequality of natural numbers implies Boolean inequality. | |
| -/ | |
| theorem Nat.ble_eq_true_of_le (h : LE.le n m) : Eq (Nat.ble n m) true := | |
| match h with | |
| | Nat.le.refl => Nat.ble_self_eq_true n | |
| | Nat.le.step h => Nat.ble_succ_eq_true (ble_eq_true_of_le h) | |
| ``` | |
| ``` | |
| /-- | |
| Propositional Extensionality. | |
| If two propositions are logically equivalent (that is, if each implies the other), | |
| then they are equal; each may replace the other in all contexts. | |
| -/ | |
| axiom propext {a b : Prop} : (a ↔ b) → a = b | |
| /-- | |
| The Axiom of Choice. | |
| `Nonempty α` is a proof that `α` has an element, but the element itself is | |
| erased. The axiom `choice` supplies a particular element of `α` given only | |
| this proof. | |
| In particular, this axiom is | |
| [global choice](https://en.wikipedia.org/wiki/Axiom_of_global_choice), which | |
| is slightly stronger than the axiom of choice in ZFC. | |
| The axiom of choice is used to derive the law of the excluded middle | |
| (`Classical.em`), so it may show up in axiom listings for proofs that do | |
| not obviously use choice. | |
| This axiom can be used to construct “data” (that is, elements of non-Prop | |
| types). There is no algorithmic interpretation of this axiom, so any definition | |
| that would involve executing `Classical.choice` or other axioms must be marked | |
| `noncomputable`. The compiler will not produce executable code for such | |
| definitions, but they can be reasoned about in the logic. | |
| -/ | |
| axiom Classical.choice {α : Sort u} : Nonempty α → α | |
| ``` | |
| #### Predicates and Propositions | |
| Predicates and new propositions should be documented either with an | |
| English-language translation of their meaning or with a noun phrase | |
| that describes their function. Try to phrase the docstring differently | |
| from the Lean syntax to increase accessibility. For the most basic | |
| connectives, the docstring should also include the words that are | |
| commonly used to refer to the concept, like “conjunction”, “logical | |
| equivalence”, or “bi-implication”. | |
| For most inductively defined predicates, constructors and projections | |
| should be documented according to a plain reading of their logical | |
| meaning. | |
| For basic connectives, constructors and projections should be | |
| documented according to how they are used in proofs. In particular, | |
| constructors should be documented as the corresponding introduction | |
| rule and projections should be documented as elimination rules. | |
| Definitions of predicates should include the meaning of the right-hand | |
| side of the definition in the docstring, because the docstring is | |
| visible in situations where the definition is not (e.g. hovers). | |
| ##### Examples | |
| ``` | |
| /-- | |
| The conjunction of two propositions. `And a b` is typically written `a ∧ b`. | |
| -/ | |
| @[pp_using_anonymous_constructor] | |
| structure And (a b : Prop) : Prop where | |
| /-- Proves `a ∧ b`, given a proof of `a` and a proof of `b`. -/ | |
| intro :: | |
| /-- Given a proof `h : a ∧ b`, proves the left conjunct `a`. -/ | |
| left : a | |
| /-- Given a proof `h : a ∧ b`, proves the right conjunct `b`. -/ | |
| right : b | |
| /-- | |
| The disjunction of two propositions. `Or a b` is typically written `a ∨ b`. | |
| -/ | |
| inductive Or (a b : Prop) : Prop where | |
| /-- Proves `a ∨ b`, given a proof of `a`. -/ | |
| | inl (h : a) : Or a b | |
| /-- Proves `a ∨ b`, given a proof of `b`. -/ | |
| | inr (h : b) : Or a b | |
| /-- | |
| An equivalence relation `(· ~ ·) : α → α → Prop` is a relation that is: | |
| * reflexive: `x ~ x` | |
| * symmetric: `x ~ y` implies `y ~ x` | |
| * transitive: `x ~ y` and `y ~ z` implies `x ~ z` | |
| Equality is an equivalence relation, and equivalence relations share many of | |
| the properties of equality. In particular, `Quot α r` is most well behaved | |
| when `r` is an equivalence relation. In this case, use `Quotient` instead. | |
| -/ | |
| structure Equivalence {α : Sort u} (r : α → α → Prop) : Prop where | |
| /-- An equivalence relation is reflexive: `x ~ x`. -/ | |
| refl : ∀ x, r x x | |
| /-- An equivalence relation is symmetric: `x ~ y` implies `y ~ x`. -/ | |
| symm : ∀ {x y}, r x y → r y x | |
| /-- An equivalence relation is transitive: `x ~ y` and `y ~ z` implies `x ~ z`. -/ | |
| trans : ∀ {x y z}, r x y → r y z → r x z | |
| /-- | |
| Lexicographical order for products. | |
| A pair is lexicographically less than another pair if its first projection is | |
| smaller, or if its first projection is equal and its second projection is smaller. | |
| That is, `(x₁, y₁) < (x₂, y₂)` when `x₁ < x₂` or `x₁ = x₂` and `y₁ < y₂`. | |
| -/ | |
| def Prod.lexLt [LT α] [LT β] (s : α × β) (t : α × β) : Prop := | |
| s.1 < t.1 ∨ (s.1 = t.1 ∧ s.2 < t.2) | |
| /-- | |
| `xs` is a permutation of `ys`. | |
| `Perm xs ys` is normally written `xs ~ ys`. | |
| -/ | |
| inductive Perm : (xs : List α) → (ys : List α) → Prop | |
| /-- The empty list is a permutation of itself. -/ | |
| | nil : Perm [] [] | |
| /-- | |
| If one list is a permutation of another, then adding the same element to the head of each yields | |
| a permutation. | |
| -/ | |
| | cons (x : α) {xs ys : List α} : Perm xs ys → Perm (x :: xs) (x :: ys) | |
| /-- | |
| Swapping the first two elements of a list yields a permutation. | |
| -/ | |
| | swap (x y : α) (xs : List α) : Perm (y :: x :: xs) (x :: y :: xs) | |
| /-- `Perm` is transitive. -/ | |
| | trans {xs ys zs : List α} : Perm xs ys → Perm ys zs → Perm xs zs | |
| ``` | |
| #### Constants | |
| Docstrings for constants should have the following structure: | |
| * Short summary | |
| * Details | |
| * Examples | |
| The **short summary** should be 1–3 sentences (ideally 1) and provide | |
| enough information for most readers to quickly decide whether the | |
| constant is relevant to their task. The first (or only) sentence of | |
| the short summary should be a *sentence fragment* in which the subject | |
| is implied to be the documented item, written in present tense | |
| indicative, or a *noun phrase* that characterizes the documented | |
| item. Subsequent sentences should be complete sentences. If no verb | |
| seems to make sense, a noun phrase punctuated as a sentence is | |
| acceptable. If the signature names parameters, then the short summary | |
| may refer to them. The summary should be written as a single | |
| paragraph. | |
| **Details**, if needed, may be 1-3 paragraphs that describe further | |
| relevant information. They may insert links as needed. The details may | |
| include explanatory examples that can’t necessarily be machine checked | |
| and don’t fit the format. | |
| **Examples** should be in one of two formats, following the line | |
| `Examples:` (or `Example:` if there’s exactly one): | |
| * A bulleted list of short examples, following the line | |
| `Examples:`. Short examples are equalities, written in inline code | |
| elements, where both sides should be equal terms with the same | |
| type. Free variables are treated equivalently to automatically | |
| inserted implicit parameters. Typically, the left side reduces to | |
| the right. The two sides don’t need to be definitionally | |
| equal. Eventually, a variety of strategies will be used to validate | |
| the examples, including definitional equality, equality of | |
| propositions modulo the default simp set, and equality of closed | |
| terms modulo `#eval`. For types, short examples may alternately be | |
| terms that illustrate the usage of the type together with very brief | |
| explanations. | |
| * Alternating code blocks that indicate input and output, following | |
| the line `Examples:`. The input should be marked as Lean using | |
| Markdown’s language indication notation, with the `example` class, | |
| and the output should be marked as `output`. Each input should | |
| contain one or more Lean commands. There may be zero or more outputs | |
| for each input, and they should be compared as with the default | |
| settings for `#guard_msgs` (though this isn't yet automatically | |
| checked). | |
| ##### Examples | |
| ````lean | |
| /-- | |
| Applies the function `f` to each element of the list `xs`, returning a list of the results. | |
| The results are in the same order as the corresponding inputs. This takes linear time: O(|`xs`|). | |
| Examples: | |
| * `map String.length ["a", "21", ""] = [1, 2, 0]` | |
| * `map Nat.succ [] = []` | |
| -/ | |
| @[specialize] def map (f : α → β) : (xs : List α) → List β | |
| | [] => [] | |
| | a::as => f a :: map f as | |
| /-- | |
| Returns the current thread's standard input stream. | |
| Use `IO.setStdin` to replace the current thread's standard input stream. | |
| -/ | |
| @[extern "lean_get_stdin"] opaque getStdin : BaseIO FS.Stream | |
| /-- | |
| Computes a value by iteration from a starting state `a`. | |
| At each step, `f` is applied to the current state. `f` may return either a new state for further | |
| iteration or a final value that stops iteration. | |
| Example: | |
| ```lean example | |
| #eval iterate 6 fun x => do | |
| if x < 5 then | |
| pure (.inr ()) | |
| else | |
| IO.println x | |
| pure (.inl (x - 1)) | |
| ``` | |
| ```output | |
| 6 | |
| 5 | |
| ``` | |
| -/ | |
| @[specialize] partial def iterate (a : α) (f : α → IO (Sum α β)) : IO β := do | |
| let v ← f a | |
| match v with | |
| | Sum.inl a => iterate a f | |
| | Sum.inr b => pure b | |
| /-- | |
| Checks whether the provided proposition `c` is true or false and invokes the corresponding | |
| branch `t` or `e` with a suitable proof. | |
| The "dependent" `if-then-else`, normally written via the notation `if h : c then t else e`, is | |
| syntactic sugar for `dite c (fun h => t) (fun h => e)`. As a result, the code in each branch | |
| can observe the truth or falsity of the condition. | |
| For example, `GetElem.getElem arr i h`, normally written `arr[i]` with `h` found automatically, | |
| expects a proof `h : i < arr.size` in order to avoid a bounds check. This bounds check can be | |
| lifted to a branch: `if h : i < arr.size then arr[h] else ...`, and one bounds check can be used | |
| for multiple array accesses. | |
| -/ | |
| @[macro_inline] def dite {α : Sort u} (c : Prop) [h : Decidable c] (t : c → α) (e : Not c → α) : α := | |
| h.casesOn e t | |
| ```` | |
| #### Inductive Types | |
| Type constructors and constructors follow the same conventions as | |
| other constants. The short description will often use a noun phrase to | |
| characterize them. Logical content should follow the conventions | |
| described for theorems. | |
| ##### Examples | |
| ``` | |
| /-- | |
| A linked list with elements of type `α`. | |
| Like `Array`, `List` represents an ordered sequence. Their performance | |
| characteristics differ, however, and are described in [the Lean Language Reference](manual://...). | |
| -/ | |
| inductive List (α : Type u) where | |
| /-- The empty list, typically written `[]`. -/ | |
| | nil : List α | |
| /-- | |
| A list in which the first element is `head` and the rest of the list is `tail`, | |
| typically written `head :: tail`. | |
| -/ | |
| | cons (head : α) (tail : List α) : List α | |
| ``` | |
| #### Structures | |
| Type constructors, projections, and constructors follow the same | |
| conventions as other constants. The short description will often use a | |
| noun phrase to characterize all three; fields should be described | |
| according to what they contain, rather than as functions that retrieve | |
| the contents. Logical content should follow the conventions described | |
| for theorems. Structure field docstrings may refer to any of the | |
| fields, in addition to names bound in the signature. | |
| ##### Examples | |
| ``` | |
| /-- | |
| All the elements of some base type that satisfy a predicate. | |
| `Subtype p`, usually written as `{x : α // p x}`, is a type which | |
| represents all the elements `x : α` for which `p x` is true. | |
| Logically, it is a pair-like type. If `v : α` and `h : p x`, then | |
| `⟨v, h⟩ : {x // p x}`. There is a coercion from `⟨v, h⟩ : {x // p x}` | |
| to `v : α`. | |
| -/ | |
| @[pp_using_anonymous_constructor] | |
| structure Subtype {α : Sort u} (p : α → Prop) where | |
| /-- | |
| The underlying element in the base type. | |
| This is applied as a coercion when the expected type is `α`. | |
| -/ | |
| val : α | |
| /-- | |
| The value `val` satisfies the predicate. | |
| -/ | |
| property : p val | |
| /-- | |
| A section or “slice” of an array that shares the underlying memory allocation. | |
| Subarrays can be used to avoid unnecessary copying and allocation of arrays. However, | |
| subarrays retain a reference to their underlying array. The existence of multiple | |
| subarrays from the same array will thus prevent array operations from being optimized | |
| into mutation, even if the subarrays are disjoint. | |
| -/ | |
| structure Subarray (α : Type u) where | |
| /-- | |
| The underlying array. | |
| -/ | |
| array : Array α | |
| /-- | |
| The first index in the subarray, inclusive. | |
| -/ | |
| start : Nat | |
| /-- | |
| The last index in the subarray, exclusive. | |
| -/ | |
| stop : Nat | |
| /-- | |
| The start of the subarray is not greater than the end. | |
| -/ | |
| start_le_stop : start ≤ stop | |
| /-- | |
| The end of the subarray is within bounds for the underlying array. | |
| -/ | |
| stop_le_array_size : stop ≤ array.size | |
| ``` | |
| #### Classes | |
| Docstrings for class declarations are likely to appear in hovers in | |
| error messages experienced by new users. It’s important that the | |
| docstring is clearly connected to any notation that the class | |
| overloads and that it uses accessible language. | |
| ##### Examples | |
| ``` | |
| /-- | |
| Addition of two terms that don't necessarily have the same type. Instances are used to assign | |
| meaning to the `+` operator. | |
| `HAdd` is short for "heterogeneous addition." | |
| -/ | |
| class HAdd (α : Type u) (β : Type v) (γ : outParam (Type w)) where | |
| /-- | |
| `a + b` computes the sum of `a` and `b`. | |
| The precise meaning of this operation depends on the types of `a`, `b`, and the | |
| entire term. | |
| -/ | |
| hAdd : α → β → γ | |
| ``` | |
| #### Syntax Categories | |
| Syntax categories should be described by what they represent. Their | |
| documentation should consist of a noun phrase that describes the | |
| category, pluralized and punctuated as a sentence, followed by any | |
| additional necessary information in complete sentences in paragraph | |
| form. If the docstring contains only a noun phrase, don’t punctuate | |
| it. | |
| ##### Examples | |
| ``` | |
| /-- JSON literals -/ | |
| declare_syntax_cat json (behavior := symbol) | |
| ``` | |
| #### Syntax Rules | |
| Syntax rules and parsers should be described by singular noun | |
| phrases. Test the docstrings and ensure that they make sense in the | |
| context of hovers. Remember to use a suitable `recommended_spelling` | |
| command for term notation. | |
| ##### Examples | |
| ``` | |
| /-- JSON array -/ | |
| syntax "[" json,* "]" : json | |
| /-- | |
| JSON identifier. | |
| This is used as a key in an object. | |
| -/ | |
| syntax jsonIdent := ident <|> str | |
| /-- JSON key/value pair -/ | |
| syntax jsonField := jsonIdent ": " json | |
| /-- JSON object -/ | |
| syntax "{" jsonField,* "}" : json | |
| /-- A JSON literal as a Lean term -/ | |
| syntax "json% " json : term | |
| /-- An `rcases` pattern is an `rintro` pattern -/ | |
| syntax (name := rintroPat.one) rcasesPat : rintroPat | |
| /-- | |
| A multi-argument binder for a sequence of patterns. | |
| The pattern `(pat1 ... : ty)` binds the variables in the pattern and ensures that each | |
| has type `ty`. | |
| -/ | |
| syntax (name := rintroPat.binder) (priority := default+1) -- to override rcasesPat.paren | |
| "(" rintroPat+ (" : " term)? ")" : rintroPat | |
| /-- | |
| A bijection between two types is a pair of mutually inverse functions between them. | |
| -/ | |
| structure Bijection (α β) where | |
| into : α → β | |
| outOf : β → α | |
| /- Properties omitted -/ | |
| @[inherit_doc Bijection] | |
| infix:50 " ⇔ " => Bijection | |
| recommended_spelling "bij" for "⇔" in [Bijection, «term_⇔_»] | |
| ``` | |
| #### Tactics | |
| Docstrings for tactics should have the following structure: | |
| * Short summary | |
| * Details | |
| * Variants | |
| * Examples | |
| Sometimes more than one declaration is needed to implement what the user | |
| sees as a single tactic. In that case, only one declaration should have | |
| the associated docstring, and the others should have the `tactic_alt` | |
| attribute to mark them as an implementation detail. | |
| The **short summary** should be 1–3 sentences (ideally 1) and provide | |
| enough information for most readers to quickly decide whether the | |
| tactic is relevant to their task. The first (or only) sentence of | |
| the short summary should be a full sentence in which the subject | |
| is an example invocation of the tactic, written in present tense | |
| indicative. If the example tactic invocation names parameters, then the | |
| short summary may refer to them. For the example invocation, prefer the | |
| simplest or most typical example. Explain more complicated forms in the | |
| variants section. If needed, abbreviate the invocation by naming part of | |
| the syntax and expanding it in the next sentence. The summary should be | |
| written as a single paragraph. | |
| **Details**, if needed, may be 1-3 paragraphs that describe further | |
| relevant information. They may insert links as needed. This section | |
| should fully explain the scope of the tactic: its syntax format, | |
| on which goals it works and what the resulting goal(s) look like. It | |
| should be clear whether the tactic fails if it does not close the main | |
| goal and whether it creates any side goals. The details may include | |
| explanatory examples that can’t necessarily be machine checked and | |
| don’t fit the format. | |
| If the tactic is extensible using `macro_rules`, mention this in the | |
| details, with a link to `lean-manual://section/tactic-macro-extension` | |
| and give a one-line example. If the tactic provides an attribute or a | |
| command that allows the user to extend its behavior, the documentation | |
| on how to extend the tactic belongs to that attribute or command. In the | |
| tactic docstring, use a single sentence to refer the reader to this | |
| further documentation. | |
| **Variants**, if needed, should be a bulleted list describing different | |
| options and forms of the same tactic. The reader should be able to parse | |
| and understand the parts of a tactic invocation they are hovering over, | |
| using this list. Each list item should describe an individual variant | |
| and take one of two formats: the **short summary** as above, or a | |
| **named list item**. A named list item consists of a title in bold | |
| followed by an indented short paragraph. | |
| Variants should be explained from the perspective of the tactic's users, not | |
| their implementers. A tactic that is implemented as a single Lean parser may | |
| have multiple variants from the perspective of users, while a tactic that is | |
| implemented as multiple parsers may have no variants, but merely an optional | |
| part of the syntax. | |
| **Examples** should start with the line `Examples:` (or `Example:` if | |
| there’s exactly one). The section should consist of a sequence of code | |
| blocks, each showing a Lean declaration (usually with the `example` | |
| keyword) that invokes the tactic. When the effect of the tactic is not | |
| clear from the code, you can use code comments to describe this. Do | |
| not include text between examples, because it can be unclear whether | |
| the text refers to the code before or after the example. | |
| ##### Example | |
| ```` | |
| `rw [e]` uses the expression `e` as a rewrite rule on the main goal, | |
| then tries to close the goal by "cheap" (reducible) `rfl`. | |
| If `e` is a defined constant, then the equational theorems associated with `e` | |
| are used. This provides a convenient way to unfold `e`. If `e` has parameters, | |
| the tactic will try to fill these in by unification with the matching part of | |
| the target. Parameters are only filled in once per rule, restricting which | |
| later rewrites can be found. Parameters that are not filled in after | |
| unification will create side goals. If the `rfl` fails to close the main goal, | |
| no error is raised. | |
| `rw` may fail to rewrite terms "under binders", such as `∀ x, ...` or `∃ x, | |
| ...`. `rw` can also fail with a "motive is type incorrect" error in the context | |
| of dependent types. In these cases, consider using `simp only`. | |
| * `rw [e₁, ... eₙ]` applies the given rules sequentially. | |
| * `rw [← e]` or `rw [<- e]` applies the rewrite in the reverse direction. | |
| * `rw [e] at l` rewrites with `e` at location(s) `l`. | |
| * `rw (occs := .pos L) [e]`, where `L` is a literal list of natural numbers, | |
| only rewrites the given occurrences in the target. Occurrences count from 1. | |
| * `rw (occs := .neg L) [e]`, where `L` is a literal list of natural numbers, | |
| skips rewriting the given occurrences in the target. Occurrences count from 1. | |
| Examples: | |
| ```lean | |
| example {a b : Nat} (h : a + a = b) : (a + a) + (a + a) = b + b := by rw [h] | |
| ``` | |
| ```lean | |
| example {f : Nat -> Nat} (h : ∀ x, f x = 1) (a b : Nat) : f a = f b := by | |
| rw [h] -- `rw` instantiates `h` only once, so this is equivalent to: `rw [h a]` | |
| -- goal: ⊢ 1 = f b | |
| rw [h] -- equivalent to: `rw [h b]` | |
| ``` | |
| ```` | |
| ## Dictionary | |
| Use the following terminology: | |
| | **Preferred term** | **Other terms** | | |
| | --- | --- | | |
| | lexicographical | lexicographic | | |
| | discriminant (of a match) | scrutinee, target | | |
| | recursor | eliminator, induction principle | | |
| | syntax category | nonterminal | | |
| | term (for Lean terms) | expression, statement | | |
| | heterogeneous equality | John Major equality | | |
| | inductive type/structure | datatype | | |
| | instance synthesis | typeclass search, typeclass resolution | | |
| Some of the other terms are suitable as more specific terms than the | |
| preferred terms. For example, while “induction principle” should not | |
| be used for generated recursors in general, it's a great description | |
| of a special-purpose reasoning tool provided by a library. |