Zulip Chat Archive
Stream: lean4
Topic: Converting from doSeq to doSeqItem
Eric Wieser (Nov 15 2023 at 11:04):
Is there a better way to write the following?
def doSeqToItem {m: Type → Type} [Monad m] [MonadRef m] [MonadQuotation m]
(t : TSyntax ``doSeq) : m (TSyntax ``doSeqItem) :=
`(doSeqItem| if h : True then $t else (h trivial).elim)
Mario Carneiro (Nov 15 2023 at 11:09):
import Lean
open Lean Parser Term
def doSeqToItem {m: Type → Type} [Monad m] [MonadRef m] [MonadQuotation m]
(t : TSyntax ``doSeq) : m (TSyntax ``doSeqItem) :=
`(doSeqItem| do $t)
Mario Carneiro (Nov 15 2023 at 11:09):
you'd think this starts a new do
scope, but it doesn't
Mario Carneiro (Nov 15 2023 at 11:12):
example :
(Id.run do
if true then
do
return 1
else
pure 0
pure 10
) = 1 := rfl
example :
(Id.run do
if true then
(do
return 1)
else
pure 0
pure 10
) = 10 := rfl
Eric Wieser (Nov 15 2023 at 11:20):
And a follow up question, how do I go from a TSyntax `doElem
to a TSyntax `Lean.Parser.Term.doSeq : Type
?
Eric Wieser (Nov 15 2023 at 11:24):
(and why is it a fake `doElem
name and not a real declaration unlike doSeq
?)
Mario Carneiro (Nov 15 2023 at 11:26):
doElem
and a few others like term
use unqualified names for the syntax kind, I think this is an outdated style and we would prefer they are all declarations but for now there are fake declarations like src#Lean.Parser.Category.term for hanging the docs for these
Mario Carneiro (Nov 15 2023 at 11:28):
what they have in common is these are all extensible syntax categories, not individual definitions
Mario Carneiro (Nov 15 2023 at 11:30):
def doElemToSeq {m: Type → Type} [Monad m] [MonadRef m] [MonadQuotation m]
(t : TSyntax `doElem) : m (TSyntax ``doSeq) :=
`(doSeq| $t:doElem)
Eric Wieser (Nov 15 2023 at 11:32):
It's not entirely clear to me what the difference between doSeqItem
and doElem
is
Mario Carneiro (Nov 15 2023 at 11:34):
not much:
def doSeqItem := leading_parser
ppLine >> doElemParser >> optional "; "
Eric Wieser (Nov 15 2023 at 12:02):
Thanks! The context here is https://github.com/leanprover-community/quote4/pull/27, where return
is misbehaving
Mario Carneiro (Nov 15 2023 at 12:12):
oh that's right, quote4 had this horrible hack with comefrom
being laundered through assert!
to work around the fact that do
elaboration is not extensible
Eric Wieser (Nov 15 2023 at 12:13):
To me it looks like comefrom
is just an optimization
Eric Wieser (Nov 15 2023 at 12:13):
(in order to avoid duplicating a match alternative
Mario Carneiro (Nov 15 2023 at 12:13):
this line
elabTerm (← `(have $n:ident : ?m := (do $b:doSeq); $body)) expectedType
is adding a new do
scope
Mario Carneiro (Nov 15 2023 at 12:14):
possibly on purpose?
Mario Carneiro (Nov 15 2023 at 12:17):
no that's definitely the bug, although maybe it's not clear how to elaborate that in the context of the outer do block
Eric Wieser (Nov 15 2023 at 12:17):
I assume you saw that my PR deleted those lines already?
Mario Carneiro (Nov 15 2023 at 12:19):
can you explain what the new version is doing by example?
Eric Wieser (Nov 15 2023 at 12:20):
Its directly substituting the alternations as syntax, rather than trying to declare them as let
s and resume them
Eric Wieser (Nov 15 2023 at 12:20):
I think the problem is that _qq_match
is handling the alternation itsel
Mario Carneiro (Nov 15 2023 at 12:21):
does this involve duplicating syntax?
Eric Wieser (Nov 15 2023 at 12:21):
Yes, it does. Is that bad for other reasons?
Mario Carneiro (Nov 15 2023 at 12:23):
it involves duplicating it in a loop, no less
Eric Wieser (Nov 15 2023 at 12:23):
I think I understand a way to avoid doing that (build an Option
of a sigma type, and ultimately do the final match on that), but it might be a larger refactor than I have time for today
Mario Carneiro (Nov 15 2023 at 12:23):
this seems like it would explode exponentially
Mario Carneiro (Nov 15 2023 at 12:24):
The usual technique used for the do
elaborator is to capture the remainder of the block into a closure and jump to it under certain circumstances
Mario Carneiro (Nov 15 2023 at 12:24):
I think that's what the comefrom
stuff was about
Eric Wieser (Nov 15 2023 at 12:24):
But that's not an option because it interferes with the real do notation
Eric Wieser (Nov 15 2023 at 12:25):
I think the solution here is that
let ~q(f $x $y) := e | alt
should be a macro for
let some ⟨x, y, match_eq⟩ := (←do_q_match ~q(f $x $y) e) | alt
Mario Carneiro (Nov 15 2023 at 12:30):
what's the match_eq
part about?
Mario Carneiro (Nov 15 2023 at 12:32):
Well, actually rather than doing two macro expansions I would just suggest building both the ⟨x, y⟩
pattern and the expression to go in for do_q_match ~q(f $x $y) e
in a single go
Eric Wieser (Nov 15 2023 at 12:40):
Mario Carneiro said:
what's the
match_eq
part about?
It contains the $e =Q f $x $y
term
Last updated: Dec 20 2023 at 11:08 UTC