Zulip Chat Archive
Stream: metaprogramming / tactics
Topic: Confused by Metavariable occurance
William Sørensen (Jul 31 2024 at 15:02):
I was trying to see what certain expressions elab to so i wrote this little piece of code
open Parser.Term
elab "#test" t:term : command =>
runTermElabM fun _ => do
let x ← Elab.Term.elabTerm t none
let xType ← inferType x
let xChecked ← Elab.Term.ensureHasType xType x
let xFinal ← instantiateMVars xChecked
dbg_trace (← ppExpr xFinal)
dbg_trace (repr xFinal)
#test (match Nat.zero with | _ => Nat.zero)
#test let rec x := 0; x
but it yielded some very suprising results:
?m.17667
Lean.Expr.mvar (Lean.Name.mkNum `_uniq 17667)
On the line with the match.
(fun x => x) ?m.17669
Lean.Expr.app
(Lean.Expr.lam
`x
(Lean.Expr.mvar (Lean.Name.mkNum `_uniq 17673))
(Lean.Expr.mdata
{ entries := [(`_recApp,
Lean.DataValue.ofSyntax
(Lean.Syntax.ident
(Lean.SourceInfo.original
"".toSubstring
{ byteIdx := 6701 }
"\n".toSubstring
{ byteIdx := 6702 })
"x".toSubstring
`x
[]))] }
(Lean.Expr.bvar 0))
(Lean.BinderInfo.default))
(Lean.Expr.mvar (Lean.Name.mkNum `_uniq 17669))
On the line with the let rec
So now my question is as follows, why are these mvars appearing here? I would expect these to elab into complete exprs, why do they not?
William Sørensen (Jul 31 2024 at 15:58):
Fixed a small error, was using the wrong elab, but results are still confusing
Jannis Limperg (Jul 31 2024 at 16:33):
It seems like the elaborator decided to postpone some tasks; the metavariables stand in for the postponed parts of the term. If you disable postponing, you at least get an informative error for the match
. (Same behaviour as before for the let rec
, but that one also confuses me in general.)
import Lean
open Lean Lean.Meta Lean.Elab.Command Lean.Elab.Term
elab "#test" t:term : command =>
liftTermElabM do
withoutPostponing do
withSynthesize do
withoutErrToSorry do
let x ← Elab.Term.elabTerm t none
let xType ← inferType x
let xChecked ← Elab.Term.ensureHasType xType x
let xFinal ← instantiateMVars xChecked
dbg_trace (← ppExpr xFinal)
dbg_trace (repr xFinal)
#test (match Nat.zero with | _ => Nat.zero)
#test let rec x := 0; x
The withSynthesize
and withoutErrToSorry
don't affect this example, but are needed in general if you want to elaborate something without allowing any funny business.
(Btw #mwe in future please, you were missing an import
and some open
s.)
William Sørensen (Aug 01 2024 at 11:42):
Ok nice thanks for the help, maybe Ill find some hack to avoid the let rec then...
William Sørensen (Aug 12 2024 at 10:20):
For closure on this, it looks like let rec
s are lifted up out of the expression and elab'd kinda like a def
so i think this explains why the let rec did not elab, it needed a place to be lifted. idk this is kinda off vibes but noteworthy anyway
Last updated: May 02 2025 at 03:31 UTC