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