Zulip Chat Archive
Stream: lean4
Topic: Antiquotations in Qq
Eric Wieser (Jul 16 2023 at 13:01):
Does Qq have antiquotations for expressions, or only free variables? This doesn't seem to work:
import Qq
import Mathlib.Data.Fin.Basic
open Qq
#check q(Fin $(2 + 1))
Gabriel Ebner (Jul 16 2023 at 17:33):
This works:
#check let n : Nat := 2 + 1; q(Fin $n)
Antiquotations are assumed to have type Q(_)
.
Eric Wieser (Jul 16 2023 at 18:26):
So is $(x)
not the same as $x
? Or is there a special rule above because n
is a free variable of known type?
Mario Carneiro (Jul 16 2023 at 18:27):
the latter
Eric Wieser (Jul 16 2023 at 19:56):
Is this just a syntactic limitation, or are there good reasons to require it to use free variables?
Eric Wieser (Jul 16 2023 at 22:09):
Hmm, I'm still confused here:
import Qq
open scoped Qq
example (x : Nat) : Q(Nat) := q($x) -- ok
example (x : Nat) : Q(Nat) := q($(x)) -- ok
example (x : Nat) : Q(Nat) := q($((x))) -- error, type mismatch, got `Nat` expected `QQ _`
Gabriel Ebner (Jul 16 2023 at 22:42):
This is understandably confusing. $x
is the same as $(x)
(same syntax), but $((x))
is different (contains a parenthesis node). And quote4 transforms non-identifier antiquotations to let x' := (x); q($x')
.
Eric Wieser (Jul 16 2023 at 22:48):
What does quote4 do to identifiers? Is there a transformation toQ
such that $(x)
is equivalent to $(toQ x)
?
Eric Wieser (Jul 16 2023 at 22:48):
(i.e. for when x : Nat
)
Gabriel Ebner (Jul 16 2023 at 22:50):
The automatic toExpr
is only applied to variables in the local context.
Eric Wieser (Jul 16 2023 at 22:56):
What I meant to ask is, can this be made to work?
example (x : ℕ) : Q(ℕ) := q($(Lean.toExpr x))
Eric Wieser (Jul 16 2023 at 22:56):
Or is Lean.toExpr
the wrong function there?
Eric Wieser (Jul 16 2023 at 23:00):
Ah, q($((show Q(Nat) from Lean.toExpr x)))
works
Eric Wieser (Jul 16 2023 at 23:11):
Do we have these functions?
def toTypeExprQ (α : Type u) [Lean.ToLevel.{u}] [Lean.ToExpr α] :
Q(Sort $(Lean.toLevel.{u})) := Lean.toTypeExpr α
def toExprQ {α : Type u} [Lean.ToLevel.{u}] [Lean.ToExpr α] (x : α) :
Q($(toTypeExprQ α)) := Lean.toExpr x
-- works, but needs the :)
example (x : Nat) : Q(Nat) := q($((toExprQ x :)))
Gabriel Ebner (Jul 16 2023 at 23:24):
This works:
example (x : Nat) : Q(Nat) :=
q($(@toExprQ _ (by exact inferInstance) _ x))
Gabriel Ebner (Jul 16 2023 at 23:25):
The ToLevel
instances are obviously brittle, so I'd rather tend to a new ToExprQ Nat
type class extending ToLevel
.
Eric Wieser (Jul 16 2023 at 23:35):
#5952 contains the defs above, feel free to make the refactor you're suggesting
Gabriel Ebner (Jul 17 2023 at 01:54):
I've put in the refactor.
Last updated: Dec 20 2023 at 11:08 UTC