Zulip Chat Archive
Stream: metaprogramming / tactics
Topic: Disable hygiene for specific variables
Pavel Klimov (Nov 12 2025 at 14:31):
I want to use elaborators to automatically generate definitions. Naturally, I want to combine it from parts. Here is some basic test:
macro "m1" : command => `(
def f (x : List Nat) := x.sum
)
m1
#eval f [1, 2, 3]
It says
Unknown identifier `f`
Because f is hidden under hygiene names mangling. You can disable hygiene like in following code:
macro "m1" : command => set_option hygiene false in `(
def f (x : List Nat) := x.sum
)
m1
#eval f [1, 2, 3]
And it will work as intended. Other workaround I found when I tried to pass f as an argument to macro, and it did work, but I still want to generate identifier inside macro, so I came to following idea:
macro "m1" : command =>
let f := Lean.Syntax.ident .none "f".toSubstring `f [] |> Lean.TSyntax.mk
`(
def $f (x : List Nat) := x.sum
)
m1
#eval f [1, 2, 3]
So, it is utilizing behavior of antiquotations. Antiquotations inserted as they are. Issues comes when I want to generate x and then use it in syntax like x.sum. Why? Well, it turns out that x.sum is actually inserted in syntax as a name. And x and x.sum are different names. So, if pattern which have x.sum have different hygiene, then to make it work, I need to force them to match. Another issue is, x can be in different places which require different TSyntax kind. And, I don't know other way than just making new variable for each TSyntax kind.
Is there any good / intended way to work with situations like this, except set_option hygiene false?
Aaron Liu (Nov 12 2025 at 16:28):
Well there's Unhygienic.run
Pavel Klimov (Nov 12 2025 at 16:47):
Aaron Liu :
Well there's
Unhygienic.run
Any example? I don't understand documentation about Unhygenic. When I tried Unhygenic.run instead of set_option hygiene false, instead of f I got f._@.UnhygienicMain._hyg.1
Robin Arnez (Nov 12 2025 at 18:28):
Unhygienic.run doesn't disable hygiene but it uses dummy hygiene data.
Robin Arnez (Nov 12 2025 at 18:30):
What you're supposed to do is something similar to what you did in your third code snippet, except there's a function for it (docs#Lean.mkIdent):
open Lean
macro "m1" : command => `(def $(mkIdent `f) (x : List Nat) := x.sum)
m1
#eval f [1, 2, 3] -- works
Last updated: Dec 20 2025 at 21:32 UTC