-
Notifications
You must be signed in to change notification settings - Fork 40
feat: slightly extend meta phase section
#626
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 4 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -128,9 +128,11 @@ When it comes to actual code execution, there is no point to a definition withou | |||||||||||||
| Thus, in order to eagerly know what definitions _might_ be executed at compile time and so need to be available including their bodies (in some executable shape), any definition used as an entry point to compile-time execution has to be tagged with the new `meta` modifier. | ||||||||||||||
| This is automatically done in built-in metaprogramming syntax such as `syntax`, `macro`, and `elab` but may need to be done explicitly when manually applying metaprogramming attributes such as `@[app_delab]`. | ||||||||||||||
|
|
||||||||||||||
| A `meta` definition may access (and thus invoke) any `meta` or non-`meta` definition of the current module. | ||||||||||||||
| For accessing imported definitions, the definition must either have been marked as `meta` when it was declared or the import must be marked as such (`meta import` when the accessing definition is in the private scope and `public meta import` otherwise). | ||||||||||||||
|
|
||||||||||||||
| A `meta` definition may access (and thus invoke) other `meta` definitions only; a non-`meta` definition likewise may only access other non-`meta` definitions. | ||||||||||||||
| For imported definitions, the `meta` marker can be added after the fact using `meta import`. | ||||||||||||||
| `meta import`ing a definition already in the meta phase leaves it in that phase. | ||||||||||||||
| In addition, the import must be public if the imported definition may be compile-time executed outside the current module, i.e. if it is reachable from some public `meta` definition in the current module: use `public meta import` or, if already `meta`, `public import`. | ||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I usually prefer "declaration" over "constant" in user-facing text, is there some canonized stance on that? |
||||||||||||||
| This is usually the case, unless a definition was imported solely for use in `local` metaprograms. | ||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why is There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @david-christiansen Is this clearer? |
||||||||||||||
| ``` | ||||||||||||||
| module | ||||||||||||||
|
|
||||||||||||||
|
|
@@ -141,6 +143,13 @@ local elab "my_elab" : command => do | |||||||||||||
| ... | ||||||||||||||
| ``` | ||||||||||||||
|
|
||||||||||||||
| For convenience, `meta` also implies `partial`. | ||||||||||||||
| This can be overriden by giving an explicit `termination_by` metric (such as one suggested by `termination_by?`), which may be necessary when the type of the definition is not known to be `Nonempty`. | ||||||||||||||
|
|
||||||||||||||
| As a guideline, it is usually preferable to apply `meta` as late as possible. | ||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this text is a bit ambiguous: should it be applied late in the development process when Lean complains, or should it be done via import instead of an explicit modifier? It's the latter, but I think readers might be confused. |
||||||||||||||
| Thus helper definitions not directly registered as metaprograms do not need to be marked if they are located in a separate module. | ||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
I think this is more of a "here's the important detail" sentence than an expression of causality/implication, right?
Comment on lines
+149
to
+150
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @david-christiansen better? |
||||||||||||||
| Only the final module(s) actually registering metaprograms then should use `public meta import` to import those helpers and define its metaprograms using built-in syntax like `elab`, using `meta def`, or using `meta section`. | ||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
I think two sentences makes this easier to parse. Can we motivate this? I see two reasons: that it enables re-use and independent non-meta testing of these helpers, and that things are generally just easier when not in |
||||||||||||||
|
|
||||||||||||||
| # Common Errors and Patterns | ||||||||||||||
|
|
||||||||||||||
| The following list contains common errors one might encounter when using the module system and especially porting existing files to the module system. | ||||||||||||||
|
|
@@ -164,6 +173,11 @@ The following list contains common errors one might encounter when using the mod | |||||||||||||
| You might also see this as a kernel error when a tactic directly emits proof terms referencing specific declarations without going through the elaborator, such as for proof by reflection. | ||||||||||||||
| In this case, there is no readily available trace for debugging; consider using `@[expose] section`s generously on the closure of relevant modules. | ||||||||||||||
|
|
||||||||||||||
| : "failed to compile 'partial' definition" on `meta` definition | ||||||||||||||
|
|
||||||||||||||
| This can happen when a definition with a type that is not known to be `Nonempty` is marked `meta` or moved into a `meta section`, which both imply `partial` without a termination metric. | ||||||||||||||
| Use `termination_by?` to make the previously implicitly inferred termination metric explicit, or provide a `Nonempty` instance. | ||||||||||||||
|
|
||||||||||||||
| ## Recipe for Porting Existing Files | ||||||||||||||
|
|
||||||||||||||
| Start by enabling the module system throughout all files with minimal breaking changes: | ||||||||||||||
|
|
||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On a first read-through, the adverb came as a surprise