Zulip Chat Archive
Stream: lean4
Topic: How to use hand written parsers
Mario Carneiro (Jul 12 2021 at 22:19):
Could someone explain how I should finish this example? I get errors about missing formatters and pretty printers but I haven't figured out what to write to fix the error. I'm fine with stubbing that stuff out, I just want a custom parser for now.
import Lean
namespace Lean
namespace Parser
def evenNumLit : Parser where
fn := fun c s =>
let initStackSz := s.stackSize
let iniPos := s.pos
let s := numLitFn c s
if s.hasError then s else
let ok : Bool :=
match s.stxStack.back.isNatLit? with
| some n => n % 2 = 0
| none => false
if ok then s else s.mkErrorAt "even numeral" iniPos initStackSz
info := numLit.info
syntax (name := evenTerm) "even " evenNumLit : term
#check even 6
Wojciech Nawrocki (Jul 12 2021 at 22:29):
The following between def
and syntax
should work:
open PrettyPrinter
-- fully qualified names because the attribute forgets to check namespaces I guess
@[combinatorFormatter Lean.Parser.evenNumLit] def evenNumLit.formatter : Formatter := pure ()
@[combinatorParenthesizer Lean.Parser.evenNumLit] def evenNumLit.parenthesizer : Parenthesizer := pure ()
Mario Carneiro (Jul 12 2021 at 22:51):
Yay, a calc parser:
import Lean
namespace Lean
namespace Parser
def calcLHS : Parser where
fn c s :=
let s := symbolFn "..." c s
if s.hasError then s else
let tables := (getCategory (parserExtension.getState c.env).categories `term).get!.tables
trailingLoop tables c s
info := ("..." >> termParser).info
open PrettyPrinter Elab.Term
@[combinatorFormatter Lean.Parser.calcLHS] def calcLHS.formatter : Formatter := pure ()
@[combinatorParenthesizer Lean.Parser.calcLHS] def calcLHS.parenthesizer : Parenthesizer := pure ()
syntax (name := calcTerm) "calc " term " : " term (calcLHS " : " term)* : term
@[macro Lean.Parser.calcTerm] def expandCalc : Macro := fun stx => `(sorry)
#check calc
x ≤ y : _
... ≤ z : _
Sebastian Ullrich (Jul 13 2021 at 07:06):
Now I wonder if it would be more Lean 4-y to replace ...
with whitespace sensitivity :blush: ...
Mario Carneiro (Jul 13 2021 at 21:13):
I thought about it but that is going to cause some strange indentation, I think
Mario Carneiro (Jul 13 2021 at 21:16):
calc blocks are hard to align because you usually want the binops to line up, which means you have to either indent a lot or put the first line LHS on another line
Mac (Jul 14 2021 at 00:22):
Mario Carneiro said:
put the first line LHS on another line
Yeah, my preferred style for this has always been
foo
= bar : _
= baz : _
i.e. indent the binops on the next line
Mario Carneiro (Jul 14 2021 at 00:57):
The use of colon here is also weird. Maybe =>
is more lean 4-ish?
Mario Carneiro (Jul 14 2021 at 01:00):
But I think that actually implementing this via whitespace sensitivity will hit the same issue that the - tac
block notation had: binops currently don't check indentation, and this particular situation in calc is bad because we're putting a = term
immediately after an ambiguously ended term \n
Gabriel Ebner (Jul 14 2021 at 08:03):
Mario Carneiro said:
The use of colon here is also weird. Maybe
=>
is more lean 4-ish?
Other reasonable options would be :=
or from
or by
(in analogy to have
).
Patrick Massot (Jul 14 2021 at 08:03):
I hope this was a joke by Mario. What's the issue with :
?
Patrick Massot (Jul 14 2021 at 08:04):
By the way, didn't we have an agreement that the =>
was only for programming and we would replace it in the math parts of mathlib?
Mario Carneiro (Jul 14 2021 at 08:05):
Lean usually uses :
to mean that the type of the left side is the right side, but in calc
the meaning is flipped: the right side is a proof of the type which is written on the left
Patrick Massot (Jul 14 2021 at 08:06):
I don't think there is any risk of confusion here. But using by
or from
would be ok as well.
Mario Carneiro (Jul 14 2021 at 08:07):
Re: less =>
, I still don't know what to do about the style guide for lambdas in proofs. λ x => pf
just looks weird to me
Patrick Massot (Jul 14 2021 at 08:07):
I think almost everything would look good compared to using =>
to mean anything but implies
.
Mario Carneiro (Jul 14 2021 at 08:07):
in mathlib4 I've been using fun x => pf
but I'm not super happy about it
Patrick Massot (Jul 14 2021 at 08:08):
In the math part of mathlib I think there is a huge consensus that we simply don't want to use =>
at all.
Mario Carneiro (Jul 14 2021 at 08:08):
It also shows up in match
, induction
, cases
, ...
Patrick Massot (Jul 14 2021 at 08:09):
We could use a weird symbol if computer scientists really can't stand seeing , but not something that is clearly the ascii-art version of .
Mario Carneiro (Jul 14 2021 at 08:09):
I can't imagine not seeing it on a majority of lines even in the math part of mathlib the way lean 4 syntax is currently designed
Patrick Massot (Jul 14 2021 at 08:09):
Mario Carneiro said:
It also shows up in
match
,induction
,cases
, ...
But this is core Lean. In mathlib 4 we can change that, right?
Mario Carneiro (Jul 14 2021 at 08:10):
sure, propose away
Mario Carneiro (Jul 14 2021 at 08:10):
I don't know what mathlib 4 style is yet
Mario Carneiro (Jul 14 2021 at 08:12):
Gabriel Ebner said:
Mario Carneiro said:
The use of colon here is also weird. Maybe
=>
is more lean 4-ish?Other reasonable options would be
:=
orfrom
orby
(in analogy tohave
).
Does by
actually work here? I would think that expr by expr
would be parsed as an expression, an application expr (by expr)
Patrick Massot (Jul 14 2021 at 08:12):
Really, any weird symbol you can't recognize in the unicode table would be better than using a symbol which is well-known to have a different meaning. But of course the obvious candidate is
Mario Carneiro (Jul 14 2021 at 08:13):
I considered using ⇒
as a unicode alternative for =>
, but I think the category theory folks have that one reserved (and almost all other similar arrows as well)
Mario Carneiro (Jul 14 2021 at 08:15):
\mapsto
could work, even without a leader, similar to the dependent arrow being used for pi now
Patrick Massot (Jul 14 2021 at 08:15):
@Mario Carneiro said:
I considered using
⇒
as a unicode alternative for=>
, but I think the category theory folks have that one reserved (and almost all other similar arrows as well)
That would be even more confusing.
Mario Carneiro (Jul 14 2021 at 08:17):
but one thing I don't like about the dependent arrow is that you can't write (a : A) (b : B) -> C
, you have to write (a : A) -> (b : B) -> C
, and I would guess a similar restriction would appear for iterated lambda
Patrick Massot (Jul 14 2021 at 08:17):
That would be bad.
Mario Carneiro (Jul 14 2021 at 08:19):
we could just try to make a b c |-> d
work, it would mean we don't get the nice no-paren syntax of fun a b c => d
but that seems tolerable given that in lean 3 you need parens or $
before \lam
if it is a function argument
Gabriel Ebner (Jul 14 2021 at 08:39):
Does
by
actually work here? I would think thatexpr by expr
would be parsed as an expression, an applicationexpr (by expr)
syntax (name := calcTerm) "calc" (term "by" tactic)+ : term
@[macro Lean.Parser.calcTerm] def expandCalc : Macro | stx => do
dbg_trace stx
`(sorry)
#check calc
a ≤ b by skip
_ ≤ c by { apply le_c; assumption }
_ ≤ c by trivial
_ ≤ c by trivial
The last one is parsed as [(«term_≤_» (Term.hole "_") "≤" `c) "by" (Tactic.tacticTrivial "trivial")]
.
Sebastian Ullrich (Jul 14 2021 at 08:43):
Yes, by
's precedence is lower than e.g. fun
's, otherwise show-by etc. wouldn't work either
Mario Carneiro (Jul 14 2021 at 08:44):
so I guess that's also why foo $ by ...
needs the $
even though fun
lost it?
Sebastian Ullrich (Jul 14 2021 at 08:45):
Note that we've recently unified have-from/by to a single, simpler syntax, though we still have it in other places because show ... :=
would look really weird (to me)...
Mario Carneiro (Jul 14 2021 at 08:46):
I could get used to show ty := expr
, it would finally get rid of the useless from
keyword
Mario Carneiro (Jul 14 2021 at 08:47):
also a big +1 on that new have syntax
Patrick Massot (Jul 14 2021 at 08:48):
I like the from
keyword, it reads nicely.
Mario Carneiro (Jul 14 2021 at 08:49):
what about show ty; expr
or show ty \n expr
, similar to let
parsing? That would line up more with the tactic
Mario Carneiro (Jul 14 2021 at 08:57):
That also means that you can use show ty; by tactic
without needing show-by to be a special grammar production, which in turn means that by
can get a higher precedence and foo $ by tactic
can lose the $
Last updated: Dec 20 2023 at 11:08 UTC