Zulip Chat Archive
Stream: lean4
Topic: different dbg_traces
Damiano Testa (Jun 02 2022 at 07:04):
Dear All,
I am slowly learning my way around Lean 4 and was wondering about the different options that dbg_trace
has. I could not tell the difference between them. Below is an example where they give the same output. What are the difference between them?
Thanks!
import Lean.Elab.Tactic
elab "traces" : tactic => do
let tgt ← Lean.Elab.Tactic.getMainTarget
dbg_trace f!"with f:\n{tgt}"
dbg_trace s!"with s:\n{tgt}"
dbg_trace "neither f nor s:\n{tgt}"
theorem trace {a : Nat} : a = 0 := by
traces
/- The three traces produce the same outputs:
with f:
Eq.{1} Nat _uniq.588 (OfNat.ofNat.{0} Nat 0 (instOfNatNat 0))
with s:
Eq.{1} Nat _uniq.588 (OfNat.ofNat.{0} Nat 0 (instOfNatNat 0))
neither f nor s:
Eq.{1} Nat _uniq.588 (OfNat.ofNat.{0} Nat 0 (instOfNatNat 0))
-/
Mario Carneiro (Jun 02 2022 at 07:06):
Those aren't options of dbg_trace
Damiano Testa (Jun 02 2022 at 07:06):
Ok, but with those, dbg_trace
does not complain, with any other single character it does.
Mario Carneiro (Jun 02 2022 at 07:06):
dbg_trace
takes a format string, or an expression that implements ToString
Mario Carneiro (Jun 02 2022 at 07:07):
f!"fmt_string"
is the latter
Mario Carneiro (Jun 02 2022 at 07:07):
My guess is that the latter two are equivalent
Damiano Testa (Jun 02 2022 at 07:08):
Ah, are you saying that the f!
or s!
are attached to the stuff in quotations and have nothing to do with dbg_trace
? So, dbg_trace
simply prints out the outcome of f!"..."
or s!"..."
?
Mario Carneiro (Jun 02 2022 at 07:09):
yes
Damiano Testa (Jun 02 2022 at 07:09):
Ok, so is there a difference between s!"..."
and f!"..."
?
Mario Carneiro (Jun 02 2022 at 07:09):
the same is also true for m!
, but MessageData
doesn't implement ToString
so it doesn't work
Damiano Testa (Jun 02 2022 at 07:10):
or is this what you answered when you said "My guess is that the latter two are equivalent"?
Mario Carneiro (Jun 02 2022 at 07:10):
f!
uses ToFormat
instead of ToString
and produces a Format
Mario Carneiro (Jun 02 2022 at 07:10):
I think dbg_trace s!"str"
and dbg_trace "str"
are exactly equivalent in terms of the functions that get called
Mario Carneiro (Jun 02 2022 at 07:11):
dbg_trace f!"str"
is a bit different since it is being formatted using the ToFormat
implementation and then the format is converted to a string
Damiano Testa (Jun 02 2022 at 07:11):
Ok, so in my situation above, ToFormat
and ToString
produce the same output and dbg_trace
traces the same thing on either one of them and also on the plain "..."
, right?
Mario Carneiro (Jun 02 2022 at 07:11):
But most likely it won't be noticeably different in most cases
Mario Carneiro (Jun 02 2022 at 07:11):
right
Mario Carneiro (Jun 02 2022 at 07:12):
It's possible that the f! version might result in better looking output when the data is large enough to appear on multiple lines ...?
Mario Carneiro (Jun 02 2022 at 07:12):
assuming the type's ToString
implementation isn't just defined as x.toFormat.toString
Damiano Testa (Jun 02 2022 at 07:12):
I'll write a longet goal and see if it prints differently.
Mario Carneiro (Jun 02 2022 at 07:13):
I would guess that Expr
has a pretty solid formatter implementation so you aren't likely to see a difference there
Mario Carneiro (Jun 02 2022 at 07:13):
I'm thinking something like ToString
on a List (String x String)
or so
Mario Carneiro (Jun 02 2022 at 07:15):
indeed, take a look:
elab "traces" : tactic => do
let tgt := (List.range 20).map (fun i => (i, i))
dbg_trace f!"with f:\n{tgt}"
dbg_trace s!"with s:\n{tgt}"
dbg_trace "neither f nor s:\n{tgt}"
theorem trace {a : Nat} : a = 0 := by
traces
-- with f:
-- [(0, 0),
-- (1, 1),
-- (2, 2),
-- (3, 3),
-- (4, 4),
-- (5, 5),
-- (6, 6),
-- (7, 7),
-- (8, 8),
-- (9, 9),
-- (10, 10),
-- (11, 11),
-- (12, 12),
-- (13, 13),
-- (14, 14),
-- (15, 15),
-- (16, 16),
-- (17, 17),
-- (18, 18),
-- (19, 19)]
-- with s:
-- [(0, 0), (1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6), (7, 7), (8, 8), (9, 9), (10, 10), (11, 11), (12, 12), (13, 13), (14, 14), (15, 15), (16, 16), (17, 17), (18, 18), (19, 19)]
-- neither f nor s:
-- [(0, 0), (1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6), (7, 7), (8, 8), (9, 9), (10, 10), (11, 11), (12, 12), (13, 13), (14, 14), (15, 15), (16, 16), (17, 17), (18, 18), (19, 19)]
Damiano Testa (Jun 02 2022 at 07:16):
Ah, thanks! I was fiddling with strings and did not get anywhere!
Mario Carneiro (Jun 02 2022 at 07:16):
The reason for this is that the ToString (List A)
instance doesn't really have enough information to do line wrapping correctly
Mario Carneiro (Jun 02 2022 at 07:17):
but if it's ToFormat
then it can delay the wrapping decisions to the ToString Format
instance
Damiano Testa (Jun 02 2022 at 07:17):
Mario, do you mind if a variation of this goes into the metaprogramming in lean 4 book?
Mario Carneiro (Jun 02 2022 at 07:17):
of course not, please go ahead
Damiano Testa (Jun 02 2022 at 07:19):
Turns out, 15 iterations are sufficient for wrapping!
Mario Carneiro (Jun 02 2022 at 07:21):
you could also do something like List.replicate 5 (List.range 8)
which probably looks a bit more tidy
Damiano Testa (Jun 02 2022 at 07:23):
That's great, thanks!
Damiano Testa (Jun 02 2022 at 07:24):
One final detail, then. Is it possible to observe a difference between s!
and neither f nor s
?
Mario Carneiro (Jun 02 2022 at 07:34):
No, because it macro expands to the same thing
Damiano Testa (Jun 02 2022 at 07:36):
Perfect, thanks!
Damiano Testa (Jun 02 2022 at 07:53):
So, just to make sure that I understand.
f!"..."
produces a Format out of...
which thendbg_trace
prints, thanks for aFormat.toString
instance.s!"..."
produces a String out of...
which thendbg_trace
prints."..."
produces a String out of...
which thendbg_trace
prints passing it vias!
first, since this is howdbg_trace
is implemented.
Is this correct?
Damiano Testa (Jun 02 2022 at 07:54):
That is, at a minimum, the string passed to dbg_trace
gets an s!
applied, unless you specify that you want something else?
Damiano Testa (Jun 02 2022 at 08:31):
#26 :smile:
Mario Carneiro (Jun 02 2022 at 09:00):
The only function of s!
is to transform s!"bla {x} bla"
to ("bla " ++ toString x ++ " bla")
Mario Carneiro (Jun 02 2022 at 09:00):
f!
does the same thing but with toFormat
instead of toString
and the append instance on Format
Mario Carneiro (Jun 02 2022 at 09:02):
That is, these macros are all just to make it easier to use interpolated strings where possible, since otherwise dbg_trace "foo {x}"
would actually print "foo {x}"
which isn't what we want
Damiano Testa (Jun 02 2022 at 09:16):
Ok, thanks for the explanation!
I feel very unsure about these things and cannot always understand the source code, so I value and appreciate very much these confirmations and corrections! :smile:
Last updated: Dec 20 2023 at 11:08 UTC