Zulip Chat Archive
Stream: lean4
Topic: Defining notations involving indentation?
Tanner Swett (Jul 14 2023 at 22:41):
I'd like to define a notation that behaves similarly to the structure
command. If I understand right, it's possible (maybe mandatory?) to have the fields of the structure indented, with the end of the indented block marking the end of the structure.
With the syntax
command, is it possible to define something that responds to indentation the same way? (If not, no problem; I'll use braces and semicolons or something.)
Tanner Swett (Jul 14 2023 at 23:08):
Aha, I think I've figured it out:
syntax "variety_info " (manyIndent(ident ":" term)) : term
This allows me to write stuff like
def TwoSetsInfo := variety_info
Set1 : Type
Set2 : Type
Tanner Swett (Jul 14 2023 at 23:36):
But now I'm having trouble implementing macro rules for it. What I did manage to get working is this:
syntax "variety_info " (manyIndent(term ":" term)) : term
macro_rules
| `(variety_info
$[$name : Type]*) =>
`(VarietyInfo.mk (sorts := [$[$name],*]))
The above code allows me to write
#check variety_info
`ThisThing : Type
`ThatThing : Type
and it comes out as { sorts := [`ThisThing, `ThatThing] } : VarietyInfo
. That's _very close_ to what I actually want. What I actually want is to be able to write
#check variety_info
ThisThing : Type
ThatThing : Type
My best attempt at getting this working was to write this:
syntax "variety_info " (manyIndent(ident ":" term)) : term
macro_rules
| `(variety_info
$[$name : Type]*) =>
`(VarietyInfo.mk (sorts := [$[`$name],*]))
But I get an error at name
on the last line there:
application type mismatch
Array.map (fun name => Lean.Syntax.node2 info✝ `Lean.Parser.Term.precheckedQuot (Lean.Syntax.atom info✝ "`") name.raw)
name
argument
name
has type
Array (Lean.TSyntax `ident) : Type
but is expected to have type
Array (Lean.TSyntax `Lean.Parser.Term.quot) : Type
Presumably, writing `$name
is not the right way to say "take the identifier bound to $name
and make a name literal out of it," but what is?
Mac Malone (Jul 15 2023 at 01:24):
You are looking for $(quote name)
instead of `$name
.
Tanner Swett (Jul 26 2023 at 13:19):
Mac said:
You are looking for
$(quote name)
instead of`$name
.
Many thanks! It looks like that's one half of what I needed—the quote
function will convert a Name
to a TSyntax `term
, and the other half is converting a TSyntax `ident
to a Name
. So here's the final working code I ended up with:
open Lean (TSyntax quote)
syntax "variety_info " (manyIndent(ident ":" term)) : term
def ident_to_quoted_term (name : TSyntax `ident) : TSyntax `term :=
match name.raw with
| .ident _ _ val _ => quote val
| _ => default
macro_rules
| `(variety_info
$[$name : Type]*) =>
`(VarietyInfo.mk (sorts := [$[$(Array.map ident_to_quoted_term name)],*]))
Mario Carneiro (Jul 26 2023 at 18:16):
the other half is name.getId
Last updated: Dec 20 2023 at 11:08 UTC