Zulip Chat Archive
Stream: Is there code for X?
Topic: Extensible macros and error message
Joachim Breitner (Feb 10 2024 at 11:42):
Consider this way of extending a tactic like rfl
:
macro "test" : tactic => `(tactic| eq_refl)
macro_rules | `(tactic| test) => `(tactic| exact HEq.rfl)
example : P := by test
This produces the error message
type mismatch
HEq.rfl
has type
HEq ?m.1135 ?m.1135 : Prop
but is expected to have type
P : Sort ?u.1128
which is not really helpful for the user that wrote rfl
.
Without the second line you get
tactic 'rfl' failed, equality expected
P
P: Sort ?u.547
⊢ P
which is a bit better.
Ideally, though, one should be able to indicate that “if all registered rfl
tactics fail, print message …”.
Unfortunately, it seems that macro_rules
tries all expansions in sequence, firstly declared first, and then presents the error message from the last one, so one cannot reliably achieve this by adding fail "…"
as the first macro.
Is there a simple way out? I can do it with two macros, one to be called by the user, and one to be extended, but I wonder if there is a better idiom:
macro "testImpl" : tactic => `(tactic| eq_refl)
macro_rules | `(tactic| testImpl) => `(tactic| exact HEq.rfl) -- extend this only!
macro "test" : tactic => `(tactic| testImpl)
macro_rules | `(tactic| test) => `(tactic| fail "test failed")
example : P := by test
Damiano Testa (Feb 10 2024 at 18:52):
This has come up before. I think that the rule is that the attempts are made in reverse chronological order, until one tactic succeeds. If they all fail, the error message is the one of the first tactic.
Not always this is ideal, but this I think is the status quo.
Last updated: May 02 2025 at 03:31 UTC