Zulip Chat Archive
Stream: new members
Topic: Nesting Macros - possible? worthwhile?
Britt Anderson (Aug 25 2025 at 13:23):
My knowledge of metaprogramming is limited to some rudimentary common lisp. In trying a learning exercise for myself I was led into a side question about macros. In my case I wanted to create a "state" type that was essentially just a Fin n. I wanted to be able to create new values for a state type of a particular n without my users (or myself) having to always specify the bound or provide a proof like (by omega) that seemed boiler plate. I just wanted compile time failure for bad values. Trying to work with claude.ai to create a nested structure for my macros we came up with the following. It doesn't work, but may be a clearer way of showing what I was going for.
macro "makeFinMacro" name:ident bound:term : command =>
`(macro $name n:term : term =>
`(@Fin.mk $bound $$n (by omega)))
makeFinMacro myFin8 8
#eval myFin8 3 -- Expands to @Fin.mk 8 3 (by omega)
Of course this doesn't actually work. My question is not so much about the specifics here, though I would be happy to see a corrected implementation, but a more general comment on this type of "nesting". Is it thought to be useful? If so, is there a more standard way to implement it, and can I be pointed to something to read? Thank you.
Robin Arnez (Aug 25 2025 at 14:06):
Possible? Yes:
macro "makeFinMacro" name:ident bound:term : command =>
`(macro $(Lean.Syntax.mkStrLit name.getId.toString):str n:term : term =>
`(@Fin.mk $bound $$n (by omega)))
makeFinMacro myFin8 8
#eval myFin8 3 -- Expands to @Fin.mk 8 3 (by omega)
Worthwhile? Definitely sometimes, core also does something similar with declare_simp_like_tactic:
declare_simp_like_tactic simpOnce "simp_once" +singlePass
example (a b : Bool) : a = b := by
simp_once only [Bool.eq_iff_iff]
Britt Anderson (Aug 25 2025 at 22:43):
Thank you. Can you explain why we need $(Lean.Syntax.mkStrLit name.getId.toString):str in place of $name. I am not quite sure what to look up to understand this better. I can see the source for mkStrLit, but I don't understand why it is needed here or where to read to better understand that.
Last updated: Dec 20 2025 at 21:32 UTC