Zulip Chat Archive
Stream: lean4
Topic: can an attribute access the Syntax of a decl?
David Renshaw (Sep 15 2023 at 03:09):
Attributes can see their own syntax: https://github.com/leanprover/lean4/blob/be977579821440a5529dc1c216fab58f854b2db8/src/Lean/Attributes.lean#L50-L51
Is there a way for attributes to see the syntax of the declarations that they decorate?
@[my_attribute]
def foo := 11
Like, I want my implementation of my_attribute to have access to the Syntax of def foo := 11.
David Renshaw (Sep 15 2023 at 12:32):
The approach I've landed on is: I'm going to define my own attribute-like thing using slightly different syntax:
#[my_pseudoattribute]
def foo := 11
Then I can do anything I want in the elaboration of my_pseudoattribute, including stashing the syntax of the decl that it adorns.
Henrik Böving (Sep 15 2023 at 15:18):
What do you want to do with the syntax? You can easily get access to the elaborated version through meta programming.
David Renshaw (Sep 15 2023 at 15:29):
This is for https://github.com/dwrensha/math-puzzles-in-lean4
I want the checked-in code for a problem to contain the full solution code, and I want to be able to extract problem-only versions of the code from that.
So I want to replace the bodies of certain definitions with sorry.
David Renshaw (Sep 15 2023 at 15:32):
My pseudoattribute approach looks promising: I'll store source code spans for the code that I want to end up in the extracted file.
Eric Wieser (Sep 15 2023 at 15:33):
Note that MIL solves this via text processing and --SOLUTION/--BOTH markers
Joachim Breitner (Sep 15 2023 at 15:34):
Instead of an attribute, I'd probably implement this using a custom tactic and/or term elaborator, which stores the source code spans of it's argument. This way you could even hide only parts of a definition/proof.
(Not that I know how to do it, I'd just hope I would find out :-))
Eric Wieser (Sep 15 2023 at 15:34):
I would imagine that the #Lean for teaching stream has other solutions to this problem
David Renshaw (Sep 15 2023 at 15:35):
text processing sounds imprecise :)
Joachim Breitner (Sep 15 2023 at 15:35):
But yes, comments and regexes may be the better solution :sweat_smile:
David Renshaw (Sep 15 2023 at 15:35):
besides, I can't resist the opportunity to abuse Lean's metaprogramming facilities (and to learn more about them in the process)
Patrick Massot (Sep 15 2023 at 15:47):
The comments and python processing approach is clearly a hack and I would love to get rid of it in MIL.
David Renshaw (Sep 15 2023 at 19:55):
I got a basic version of my pseudo-attributes to work: https://github.com/dwrensha/math-puzzles-in-lean4/commit/86b0f57678c3e1e8790908b1319ec5aea458c739
David Renshaw (Sep 15 2023 at 19:56):
this dashboard is the result: https://dwrensha.github.io/math-puzzles-in-lean4/
David Renshaw (Sep 15 2023 at 19:56):
click on a problem name to get an extracted solution-less version of it
David Renshaw (Sep 15 2023 at 19:57):
click on the check or x-mark next to it to go to the source code, possibly containing a full solution
Mac Malone (Sep 16 2023 at 07:00):
@David Renshaw I would be worried about the fact that #[...] clashes with the #[...] used for Array literals. I would suggest using @@[...] or @[[...]] instead.
David Renshaw (Sep 16 2023 at 11:41):
Fair point. @@[...] looks good to me, though I am a bit sad about needing one extra keystroke
David Renshaw (Sep 16 2023 at 11:48):
alternative: %[...], where the percent sign stands for pseudo-attribute
Mac Malone (Sep 16 2023 at 17:57):
@David Renshaw Yeah, I considered %[...[, my concern there is that if Lean, Std, etc. needs and other List/Array style literal in the future it may use %[...] and the pseudo-attribute would then clash with it. Whereas, t is very unlikely add a @@[...] / @[[...]] except for a similar purpose (and attribute variant).
Thomas Murrills (Sep 16 2023 at 20:09):
I might suggest @%[...], because % usually connotes something to do with elaboration, and suggests that the @tribute works “on the same level” as elaboration/has access to syntax
Mario Carneiro (Sep 16 2023 at 21:32):
I'd rather just use @[...] and pass along the syntax
Mac Malone (Sep 16 2023 at 22:07):
@Mario Carneiro That cannot work in general. Attributes may (and are) applied in places where the syntax of the target is unavailable (e.g., attribute [foo] bar).
Mac Malone (Sep 16 2023 at 22:13):
Though, looking into it more, in @David Renshaw's case, since the token he is using is the complete attribute (e.g., #[problem_statement]), any of @[], #[], %[], etc. would work without clashing since that token will always take precedence.
Mario Carneiro (Sep 16 2023 at 22:44):
Mac Malone said:
Mario Carneiro That cannot work in general. Attributes may (and are) applied in places where the syntax of the target is unavailable (e.g.,
attribute [foo] bar).
That seems fine, you would just pass the syntax of the command, whatever it is
Thomas Murrills (Sep 16 2023 at 23:00):
You could pass an Option Syntax to make handling those “nonlocal” attribute applications easier on the person writing the attribute (so attribute [foo] bar would pass none, and you could easily throw an error)
David Renshaw (Sep 17 2023 at 13:04):
I got rid of my #[problem_statement] pseudo-attribute and now instead have declared problem to be a synonym of theorem (similar to how Mathlib does this for lemma): https://github.com/dwrensha/math-puzzles-in-lean4/commit/4115c93f3c03645420bc5dd84fccc160606416b2
David Renshaw (Sep 17 2023 at 13:06):
I intend to do something similar with #[solution_data], but it's less clear what to do with #[problem_setup], which can adorn any command (e.g. infix, open, ...).
James Gallicchio (Sep 17 2023 at 18:35):
is there a way you can use sections?
David Renshaw (Sep 17 2023 at 19:01):
Maybe! That was in fact going to be my next line of investigation.
David Renshaw (Sep 17 2023 at 19:02):
something like problem_setup_section gets included in an extracted problem, while everything else gets excluded by default
Last updated: May 02 2025 at 03:31 UTC