Zulip Chat Archive
Stream: lean4
Topic: Fun with macros
Marcus Rossel (Aug 08 2021 at 10:14):
Hm, how would the right side need to be expressed? I'm trying to get a comma-seperated list of the ls.
macro "unfold " l:(ident+) : tactic =>
`(simp only [$[$l:(ident+)],*])
... doesn't work.
Sebastian Ullrich (Aug 08 2021 at 10:21):
Ah, l:(ident+) probably is not a good idea because it will bind l to the dummy node containing all the idents. You'd have to unpack that one to use it in antiquotations, or avoid using macro.
macro "unfold " l:(ident+) : tactic =>
`(simp only [$(l.getArgs),*])
syntax "unfold " ident+ : tactic
macro_rules
| `(tactic| unfold $l*) => `(simp only [$l:ident,*])
Sebastian Ullrich (Aug 08 2021 at 10:23):
I will try to remove that footgun from macro tomorrow
Marcus Rossel (Aug 08 2021 at 10:23):
I'm guessing there are more functions like getArgs... What are those defined on?
Sebastian Ullrich (Aug 08 2021 at 10:23):
Lean.Syntax
Sebastian Ullrich (Aug 08 2021 at 10:24):
(auto completion does in fact work in that place!)
Sebastian Ullrich (Aug 08 2021 at 10:27):
For more info on antiquotations, see also §4.1 of https://arxiv.org/pdf/2001.10490.pdf#page=11
Marcus Rossel (Aug 08 2021 at 10:27):
It is not this getArgs :sweat_smile:
Sebastian Ullrich (Aug 08 2021 at 10:47):
Not quite, it's https://github.com/leanprover/lean4/blob/341b4ac652eb24471aeb55060f423fe6616025b2/src/Init/Prelude.lean#L1750-L1753 :) . You should be able to navigate there using go-to-definition.
Marcus Rossel (Aug 08 2021 at 10:55):
@Sebastian Ullrich You mention in your Hygienic-Macros-Paper that
Both commands [
syntaxandmacro_rules] can only be used at the top level; we are not currently planning support for local macros.
I've implemented both the unfold and obtain inside a namespace though, and they work. Is this intended?
Sebastian Ullrich (Aug 08 2021 at 10:56):
The "top level" is the command level. Local macros would be at the term level.
Mac (Aug 08 2021 at 12:25):
Sebastian Ullrich said:
Ah,
l:(ident+)probably is not a good idea because it will bindlto the dummy node containing all the idents. You'd have to unpack that one to use it in antiquotations, or avoid usingmacro.
Actually, you can also do this:
macro "unfold " l:many1(ident) : tactic =>
`(simp only [$l,*])
Marcus Rossel (Aug 08 2021 at 16:45):
Mac said:
Actually, you can also do this:
macro "unfold " l:many1(ident) : tactic => `(simp only [$l,*])
Not sure how it is for you, but both your and my variant give me an error along the lines of:
invalid 'simp', proposition expected
(x_0 : Sort _abstMVar.0) → x_0
Sebastian Ullrich (Aug 08 2021 at 18:02):
Here you really want the :ident :) . simp can contain more than just a term.
François G. Dorais (Aug 08 2021 at 18:57):
Doesn't simp expect a list of simpLemma? This works for me:
syntax "unfold " simpLemma,+ (location)? : tactic
macro_rules
| `(tactic|unfold $ts,* $[$loc]?) => `(tactic|simp only [$ts,*] $[$loc]?)
I don't know how to coerce an ident into a simpLemma.
Sebastian Ullrich (Aug 08 2021 at 19:22):
$[...] can be used for that
syntax "unfold " withPosition((colGe ident)+) (location)? : tactic
macro_rules
| `(tactic|unfold $ids* $[$loc]?) => `(tactic|simp only [$[$ids:ident],*] $[$loc]?)
Last updated: May 02 2025 at 03:31 UTC