Zulip Chat Archive
Stream: metaprogramming / tactics
Topic: Inaccessible optional stuff
Patrick Massot (Nov 29 2023 at 15:39):
In the following code, why is the dbg_trace
returning none
? Removing the "with"
part works.
import Lean
elab "foo" x₁:ident x₂:ident new:("with" ident)? : tactic => do
dbg_trace new
example : True := by
foo a b with c
trivial
Kyle Miller (Nov 29 2023 at 17:39):
It seems that elab
might not be generating the right pattern, but I don't really know exactly what I'm looking at.
import Lean
set_option trace.Elab.command true
set_option pp.rawOnError true
elab "foo" x₁:ident x₂:ident new:("with" ident)? : tactic => do
dbg_trace s!"{new}"
-- Generated pattern:
/-
[[(Term.quot
"`("
(tacticFoo__With_
(token_antiquot "foo" "%" "$" `x._@.Mathlib.foo._hyg.4)
(ident.antiquot "$" [] `x₁ [])
(ident.antiquot "$" [] `x₂ [])
[(optional.antiquot_suffix_splice (pseudo.antiquot "$" [] `new []) "?")])
")")]]
-/
elab_rules : tactic
| `(tactic| foo $x₁ $x₂ $[with $new]?) => dbg_trace s!"{new}"; pure ()
-- Generated pattern:
/-
[[(Tactic.quot
"`(tactic|"
(tacticFoo__With_
"foo"
(ident.antiquot "$" [] `x₁ [])
(ident.antiquot "$" [] `x₂ [])
[(optional.antiquot_scope "$" [] "[" ["with" (ident.antiquot "$" [] `new [])] "]" "?")])
")")]]
-/
Alex J. Best (Nov 29 2023 at 18:55):
import Lean
elab "foo" x₁:ident x₂:ident new:(("with" ident) ?) : tactic => do
dbg_trace new
example : True := by
foo a b with asd
trivial
at least does something, no idea how to get precisely what you want though
Alex J. Best (Nov 29 2023 at 18:56):
You can at least use .raw.getArg 1
to get the ident
Kyle Miller (Nov 29 2023 at 19:10):
This seems to be creating a null node that's either length-0 or length-2, so I guess you can do cases on the length.
import Lean
open Lean
elab "foo" x₁:ident x₂:ident new':(("with" ident) ?) : tactic => do
let new : Option Ident :=
if new'.raw.getNumArgs == 0 then none else some ⟨new'.raw.getArg 1⟩
dbg_trace new
example : True := by
foo a b with asd
foo a b
trivial
Patrick Massot (Nov 29 2023 at 19:34):
Thanks Alex and Kyle. Maybe I should have said I know how to work around this issue, but I'm completely puzzled about the issue and wanted to understand what's going on. I guess we need to ping @Sebastian Ullrich.
Sebastian Ullrich (Nov 29 2023 at 21:24):
I don't think it's clear at all here what new
should bind to, should it be something of type Option (Syntax \x Ident)
where Syntax
is the with
keyword? I believe it would be better to reject such complex patterns in macro/elab
and point users to using separate syntax+macro_rules/elab_rules
instead.
Patrick Massot (Nov 29 2023 at 22:25):
Is using elab
evil? This is news to me.
Sebastian Ullrich (Nov 29 2023 at 22:25):
Only its implementation
Sebastian Ullrich (Nov 29 2023 at 22:26):
so it is better to restrict it than somehow fix this case
Patrick Massot (Nov 29 2023 at 22:27):
To answer your question, I was hoping new
to have type Option Syntax
.
Shreyas Srinivas (Nov 29 2023 at 22:54):
I don't understand. I thought any non trivial tactic code would benefit from using elab
. What sort of footguns should we watch out for?
Thomas Murrills (Nov 29 2023 at 23:11):
If we shouldn't allow new:("with" ident)?
, would it be possible to allow elab "foo" x₁:ident x₂:ident ("with" new:ident)? : tactic => ...
in parallel to the syntax match `(tactic| foo $x₁:ident $x₂:ident $[with $new:ident]?)
?
Mario Carneiro (Nov 29 2023 at 23:12):
Patrick Massot said:
To answer your question, I was hoping
new
to have typeOption Syntax
.
This doesn't quite answer the question; what should the Syntax
be referring to? (My guess: the overall syntax node)
Thomas Murrills (Nov 29 2023 at 23:17):
I would assume the overall syntax node in that case too—I think it's fairly natural to expect chunks of syntax (like with
together with the ident) to be grouped into a whole by the structure of (T
)Syntax
, not ×
Patrick Massot (Nov 30 2023 at 04:29):
Yes, I meant the whole thing. I would hope to access the interesting bit using new.raw[1]
. But of course the ideal situation would be to be allowed to write elab "foo" x₁:ident x₂:ident ("with" new:ident)? : tactic => ...
as Thomas wrote.
Sebastian Ullrich (Nov 30 2023 at 08:30):
Patrick Massot said:
I would hope to access the interesting bit using
new.raw[1]
.
The point of these convenience commands is to never require access to raw
. It would be better to nudge people towards elab_rules
for these more complex matches than towards raw
.
But of course the ideal situation would be to be allowed to write
elab "foo" x₁:ident x₂:ident ("with" new:ident)? : tactic => ...
as Thomas wrote.
I don't see this happening, it would require effectively a copy of the entire stx
category adjusted for macro/elab with naming for subparts. Easier to nudge people towards elab_rules
.
Patrick Massot (Nov 30 2023 at 15:16):
Could you nudge me a bit more explicitly then? What's wrong with
syntax "foo" ident ident ("with" ident)? : tactic
elab_rules
| `(tactic| foo $x₁:ident $x₂:ident $[with $new]?) => ...
Sebastian Ullrich (Nov 30 2023 at 15:31):
Is it the "specify category" error?
elab_rules : tactic
| `(tactic| foo $x₁:ident $x₂:ident $[with $new]?) => _
Patrick Massot (Nov 30 2023 at 15:32):
No difference
Sebastian Ullrich (Nov 30 2023 at 15:33):
Works on my machine
import Lean
syntax "foo" ident ident ("with" ident)? : tactic
elab_rules : tactic
| `(tactic| foo $x₁:ident $x₂:ident $[with $new]?) => sorry
Patrick Massot (Nov 30 2023 at 15:34):
Sorry, I tried so many variations that I ended up in a state missing a question mark.
Patrick Massot (Nov 30 2023 at 15:36):
Thanks for your help.
Mac Malone (Dec 06 2023 at 04:08):
Sebastian Ullrich said:
I don't see this happening, it would require effectively a copy of the entire
stx
category adjusted for macro/elab with naming for subparts. Easier to nudge people towardselab_rules
.
My thought on this (and what I had hoped was the long-term plan) was to merge the macro and syntax categories for these and just produce an warning/error post-parse if subpart is named in a syntax
declaration.
Mac Malone (Dec 06 2023 at 04:10):
(In the longer-term, one could even hope to allow subpart naming in syntax
declarations and automatically generate the respective projection functions to derive them from the TSyntax
of declared syntax kind.)
Last updated: Dec 20 2023 at 11:08 UTC