Zulip Chat Archive
Stream: metaprogramming / tactics
Topic: Conditionally pretty-printing with spaces
Robert Maxton (Sep 29 2025 at 03:25):
I'm trying to make a syntax that will pretty pretty spaces between its parameters only if those parameters are not numeric literals. Specifically, I want [O2|C4], but [O n|C3], [O2|C k], and [O n|C m].
I think I need to write a PrettyPrinter.Formatter, but there's no equivalent to app_unexpander or app_delab that I'm aware of, for example, and I don't know how else to set up the trigger. (combinator_formatter termFoo at least typechecks but doesn't actually run, as verified by dbgTrace). I would like to be able to just write something like
macro "[O" (lookahead(num) <|> ppSpace) a:term "|C" (lookahead(num) <|> ppSpace) b:term "]" : term => ...
but you can't use notation with general syntax and since I don't know any way of putting explicit whitespace into a Syntax object I can't make an unexpander to make the above macro pretty-print the way I want.
Kyle Miller (Sep 29 2025 at 11:24):
You might run into some trouble here since the formatter is token-aware. It'll insert spaces automatically between O and 2 because O2 parses as an identifier.
How is O2 able to parse? It's generally not a good idea to pretty print in a way that's not parseable.
One hack you can do is use a zero-width space.
Kyle Miller (Sep 29 2025 at 11:26):
Oh, right, "[O" makes the parsing possible.
Kyle Miller (Sep 29 2025 at 11:32):
Here's a hack:
import Lean
def f : Nat → Nat := id
macro "[O" n:term "]" : term => `(f $n)
section
local syntax (name := preSpace) ppSpace term : term
end
open Lean.Syntax in
def mkPreSpace (t : Term) : Term := ⟨Lean.Unhygienic.run `(preSpace| $t)⟩
@[app_unexpander f]
def unexpandF : Lean.PrettyPrinter.Unexpander
| `($_ $n:num) => `([O $n])
| `($_ $x) => `([O $(mkPreSpace x)])
| _ => throw ()
#check [O2]
-- [O2]
variable (n : Nat)
#check [O n]
-- [O n]
Robert Maxton (Sep 30 2025 at 07:48):
So that's how you do it. I was thinking about something like that, but I'd forgotten (if I ever knew) how to set up a term generator outside of a quasiquote. Thanks, that'll work nicely!
Last updated: Dec 20 2025 at 21:32 UTC