Lean 语言参考手册

7.1. 修饰符(Modifiers)🔗

声明支持一组一致的 修饰符,它们均为可选。 修饰符会改变声明在解释上的某些方面;例如可以添加文档,或改变其作用域。 修饰符的顺序是固定的,但并非所有种类的声明都接受所有种类的修饰符。

syntax声明修饰符

修饰符按如下顺序出现,且均为可选:

  1. 文档注释;

  2. 属性 列表;

  3. 命名空间控制,指定结果名字是否为 私有受保护

  4. noncomputable 关键字,将定义排除在编译之外;

  5. unsafe 关键字;

  6. 递归修饰符 partialnonrec,分别禁用终止性证明或完全禁止递归。

declModifiers ::=
    `declModifiers` is the collection of modifiers on a declaration:
* a doc comment `/-- ... -/`
* a list of attributes `@[attr1, attr2]`
* a visibility specifier, `private` or `protected`
* `noncomputable`
* `unsafe`
* `partial` or `nonrec`

All modifiers are optional, and have to come in the listed order.

`nestedDeclModifiers` is the same as `declModifiers`, but attributes are printed
on the same line as the declaration. It is used for declarations nested inside other syntax,
such as inductive constructors, structure projections, and `let rec` / `where` definitions. A `docComment` parses a "documentation comment" like `/-- foo -/`. This is not treated like
a regular comment (that is, as whitespace); it is parsed and forms part of the syntax tree structure.

A `docComment` node contains a `/--` atom and then the remainder of the comment, `foo -/` in this
example. Use `TSyntax.getDocString` to extract the body text from a doc string syntax node. docComment?
    attributes?
    (private | protected)?
    noncomputable?
    unsafe?
    (partial | nonrec)?

文档注释 用于为其修饰的声明提供源码中的 API 文档。 需要注意,文档注释并不是真正意义上的“注释”:如果把文档注释放在不会被当作文档处理的位置,会产生语法错误。 在某些需要文本但转义会很繁琐的场景,文档注释也很有用,例如 Lean.guardMsgsCmd : command`/-- ... -/ #guard_msgs in cmd` captures the messages generated by the command `cmd` and checks that they match the contents of the docstring. Basic example: ```lean /-- error: unknown identifier 'x' -/ #guard_msgs in example : α := x ``` This checks that there is such an error and then consumes the message. By default, the command captures all messages, but the filter condition can be adjusted. For example, we can select only warnings: ```lean /-- warning: declaration uses 'sorry' -/ #guard_msgs(warning) in example : α := sorry ``` or only errors ```lean #guard_msgs(error) in example : α := sorry ``` In the previous example, since warnings are not captured there is a warning on `sorry`. We can drop the warning completely with ```lean #guard_msgs(error, drop warning) in example : α := sorry ``` In general, `#guard_msgs` accepts a comma-separated list of configuration clauses in parentheses: ``` #guard_msgs (configElt,*) in cmd ``` By default, the configuration list is `(check all, whitespace := normalized, ordering := exact)`. Message filters select messages by severity: - `info`, `warning`, `error`: (non-trace) messages with the given severity level. - `trace`: trace messages - `all`: all messages. The filters can be prefixed with the action to take: - `check` (the default): capture and check the message - `drop`: drop the message - `pass`: let the message pass through If no filter is specified, `check all` is assumed. Otherwise, these filters are processed in left-to-right order, with an implicit `pass all` at the end. Whitespace handling (after trimming leading and trailing whitespace): - `whitespace := exact` requires an exact whitespace match. - `whitespace := normalized` converts all newline characters to a space before matching (the default). This allows breaking long lines. - `whitespace := lax` collapses whitespace to a single space before matching. Message ordering: - `ordering := exact` uses the exact ordering of the messages (the default). - `ordering := sorted` sorts the messages in lexicographic order. This helps with testing commands that are non-deterministic in their ordering. For example, `#guard_msgs (error, drop all) in cmd` means to check warnings and drop everything else. The command elaborator has special support for `#guard_msgs` for linting. The `#guard_msgs` itself wants to capture linter warnings, so it elaborates the command it is attached to as if it were a top-level command. However, the command elaborator runs linters for *all* top-level commands, which would include `#guard_msgs` itself, and would cause duplicate and/or uncaptured linter warnings. The top-level command elaborator only runs the linters if `#guard_msgs` is not present. #guard_msgs 命令中的期望消息。

syntax文档注释

文档注释与普通块注释相似,但它以 /-- 开始(而非常规块注释的 /-);与普通注释一样,以 -/ 结束。

docComment ::=
    A `docComment` parses a "documentation comment" like `/-- foo -/`. This is not treated like
a regular comment (that is, as whitespace); it is parsed and forms part of the syntax tree structure.

A `docComment` node contains a `/--` atom and then the remainder of the comment, `foo -/` in this
example. Use `TSyntax.getDocString` to extract the body text from a doc string syntax node. /--
    ...
    -/

属性是可扩展的一类修饰符,用于将附加信息关联到声明上。 它们在 属性专章 中有详细说明。

若声明被标记为 private,则无法在其定义所在模块之外访问。 若声明为 protected,则打开其命名空间时不会将该名字带入作用域。

被标记为 noncomputable 的函数不会被编译,因而也不能执行。 当函数使用了非可计算的推理原则(例如选择公理或排中律)来产生与其返回结果相关的数据,或使用了因效率原因而不参与代码生成的 Lean 特性(如 递归子)时,该函数必须是 noncomputable。 即使无法编译和执行,noncomputable 函数在规范化与推理中依然十分有用。

unsafe 标记会使定义跳过内核检查,并允许其访问可能破坏 Lean 保证的功能。 使用该标记务必小心,仅在深入理解 Lean 内部机制时使用。