Writing Coq libraries and plugins¶
This section presents the part of the Coq language that is useful only to library and plugin authors. A tutorial for writing Coq plugins is available in the Coq repository in doc/plugin_tutorial.
Deprecating library objects, tactics or library files¶
You may use the following attribute to deprecate a notation,
tactic, definition, axiom, theorem or file. When renaming a definition or theorem, you can introduce a
deprecated compatibility alias using
(see the example below).
- Attribute deprecated ( since = string ,? note = string? )¶
At least one of
notemust be present. If both are present, either one may appear first and they must be separated by a comma. If they are present, they will be used in the warning message, and
sincewill also be used in the warning name and categories.
This attribute is supported by the following commands:
Theorem, and similar commands. To attach it to a compiled library file, use
It can trigger the following warnings:
- Warning Tactic qualid is deprecated since stringsince. stringnote¶
- Warning Tactic Notation qualid is deprecated since stringsince. stringnote¶
- Warning Notation string is deprecated since stringsince. stringnote¶
- Warning Ltac2 definition qualid is deprecated since stringsince. stringnote¶
- Warning Ltac2 alias qualid is deprecated since stringsince. stringnote¶
- Warning Ltac2 notation ltac2_scope+ is deprecated since stringsince. stringnote¶
Coq and its standard library follow this deprecation policy:
it should always be possible for a project written in Coq to be compatible with two successive major versions,
features must be deprecated in one major version before removal,
Coq developers should provide an estimate of the required effort to fix a project with respect to a given change,
breaking changes should be clearly documented in the public release notes, along with recommendations on how to fix a project if it breaks.
See [Zim19], Section 3.6.3, for more details.
Example: Deprecating a tactic.
- #[deprecated(since="mylib 0.9", note="Use idtac instead.")] Ltac foo := idtac.
- foo is defined
- Goal True.
- 1 goal ============================ True
- now foo.
- Toplevel input, characters 4-7: > now foo. > ^^^ Warning: Tactic foo is deprecated since mylib 0.9. Use idtac instead. [deprecated-tactic-since-mylib-0.9,deprecated-since-mylib-0.9,deprecated-tactic,deprecated,default] No more goals.
Example: Introducing a compatibility alias
Let's say your library initially contained:
- Definition foo x := S x.
- foo is defined
and you want to rename
bar, but you want to avoid breaking
your users' code without advanced notice. To do so, replace the previous
code by the following:
- Definition bar x := S x.
- bar is defined
- #[deprecated(since="mylib 1.2", note="Use bar instead.")] Notation foo := bar (only parsing).
Then, the following code still works, but emits a warning:
- Check (foo 0).
- Toplevel input, characters 7-10: > Check (foo 0). > ^^^ Warning: Notation foo is deprecated since mylib 1.2. Use bar instead. [deprecated-syntactic-definition-since-mylib-1.2,deprecated-since-mylib-1.2,deprecated-syntactic-definition,deprecated,default] bar 0 : nat