Zulip Chat Archive
Stream: general
Topic: stdout and stderr behavior
Matthew Ballard (Feb 14 2022 at 16:29):
Is there a way to write to either stdout
or stderr
without resorting to #print
or C++?
Matthew Ballard (Feb 14 2022 at 16:31):
More generally what are the semantics of writing to stdout
and stderr
in Lean 3? Some experimentation has yielded unexpected (to me) behavior.
Alex J. Best (Feb 14 2022 at 18:14):
What are you trying to accomplish? Printing during program execution, during a tactic, or something else?
You can write to stdout using docs#io.print_ln, e.g. io_test.lean
:
import system.io
meta
def main : io unit :=
do
io.run_tactic (tactic.trace "I go to stderr"),
io.print_ln "I go to stdout"
then try
lean --run io_test.lean > program.stdout 2> program.stderr
Matthew Ballard (Feb 14 2022 at 18:16):
Thanks. That was the behavior I observed. The only way I managed to get to stderr
was via tracing in a def/lemma. Is this the only way to get to stderr
?
Matthew Ballard (Feb 14 2022 at 18:17):
Generally stderr
is much less crowded so parsing it with something external is cleaner.
Alex J. Best (Feb 14 2022 at 18:20):
You can use docs#tactic.unsafe_run_io to call io methods from the tactic monad
Alex J. Best (Feb 14 2022 at 18:21):
so
meta
def main : tactic unit :=
do
tactic.unsafe_run_io $ io.print_ln "I go to stdout"
would let you trace some special tactic output to stdout if that is helpful?
Alex J. Best (Feb 14 2022 at 18:21):
Or do you want the reverse?
Julian Berman (Feb 14 2022 at 18:28):
It looks like there are "regular" file-writing looking methods if that helps too. E.g.:
import system.io
meta
def main : io unit :=
do
stderr ← io.stderr,
io.fs.put_str_ln stderr "asdf"
Julian Berman (Feb 14 2022 at 18:28):
(or io.fs.write
, or etc.)
Matthew Ballard (Feb 14 2022 at 21:27):
Thanks. These are both helpful.
This plus poking at filtering out constants should solve my use case.
Matthew Ballard (Feb 14 2022 at 21:28):
More broadly I don't understand why Lean writes to stdout
vs stderr
and would appreciate any philosophical insight
Mario Carneiro (Feb 14 2022 at 21:28):
It is pretty standard for a language to provide a println
like function that writes to stdout by default
Matthew Ballard (Feb 14 2022 at 21:29):
I agree with that. But why does tracing something in a proof environment write to stderr
Mario Carneiro (Feb 14 2022 at 21:29):
all of lean's diagnostic messages go to stderr, I think
Matthew Ballard (Feb 14 2022 at 21:29):
I would have thought errors and warnings would get pushed to stderr
Matthew Ballard (Feb 14 2022 at 21:30):
Unless I don't know how to use a computer (of which there is a serious chance), that is not the case
Mario Carneiro (Feb 14 2022 at 21:31):
Actually scratch that, it looks like all of lean's diagnostics go to stdout
Matthew Ballard (Feb 14 2022 at 21:31):
Except for tracing in a proof
Matthew Ballard (Feb 14 2022 at 21:32):
As Alex pointed out or directly writing there as Julian did
Mario Carneiro (Feb 14 2022 at 21:34):
hm, you're right, the trace
function prints to stderr even though it says
This function has a native implementation that displays the given string in the regular output stream.
Mario Carneiro (Feb 14 2022 at 21:34):
It makes some sense for it to write to stderr since it's not sequenced with regular writes
Matthew Ballard (Feb 14 2022 at 21:35):
Seems like Lean 4 follows the Lean 3 approach too
Mario Carneiro (Feb 14 2022 at 21:35):
trace_state
and tactic.trace
also write to stderr
Mario Carneiro (Feb 14 2022 at 21:37):
What is your application?
Matthew Ballard (Feb 14 2022 at 21:38):
Hmm I should take a look at trace_state
Mario Carneiro (Feb 14 2022 at 21:38):
it uses trace_fmt
internally, same with tactic.trace
Mario Carneiro (Feb 14 2022 at 21:39):
Perhaps the commonality here is that all the stderr-writing functions are using the "pure" write functions, either trace
or trace_fmt
Matthew Ballard (Feb 14 2022 at 21:39):
I am yak-shaving an autograder inside GitHub classroom. I already have a Lean 4 program that reads from naive #print axiom
' coming out of Lean 3 checking a file
Matthew Ballard (Feb 14 2022 at 21:41):
I would gain amusement from internalizing everything in Lean 3 but not much else
Julian Berman (Feb 14 2022 at 21:42):
My brain is mush at this hour but can you say more about what you're trying to do in the autograder? You're doing stuff like making sure students aren't cheating by adding axioms or whatever?
Mario Carneiro (Feb 14 2022 at 21:42):
The easiest thing to do would be to put a marker before the print axioms:
import system.io
#eval io.print_ln "==================="
#print axioms classical.em
Julian Berman (Feb 14 2022 at 21:42):
If so the programmer in me says you'll have a better time if you ignore both stdout and stderr and write to a stream you fully own with whatever info you're trying to extract
Matthew Ballard (Feb 14 2022 at 21:43):
https://github.com/c0ppelius/lean-autograding
Julian Berman (Feb 14 2022 at 21:43):
ha, ok or do the hacky thing and do that I guess
Mario Carneiro (Feb 14 2022 at 21:43):
then just trim everything before the marker in the output
Matthew Ballard (Feb 14 2022 at 21:43):
I did the hacky thing
Mario Carneiro (Feb 14 2022 at 21:43):
Or alternatively, just require that the lean proof is silent
Mario Carneiro (Feb 14 2022 at 21:44):
mathlib does that
Matthew Ballard (Feb 14 2022 at 21:44):
theorem check_problem1 : ∀ (x : Type), x = x :=
begin
check_solutions,
end
#print "Problem 1"
#print axioms check_problem1
#print "---"
Mario Carneiro (Feb 14 2022 at 21:44):
oh yeah, I forgot about #print string
Matthew Ballard (Feb 14 2022 at 21:45):
Julian Berman said:
If so the programmer in me says you'll have a better time if you ignore both stdout and stderr and write to a stream you fully own with whatever info you're trying to extract
Yes, I agree that this seems smarter
Mario Carneiro (Feb 14 2022 at 21:46):
@Julian Berman The problem is that you can't control where #print axioms
writes since it's not a regular tactic
Matthew Ballard (Feb 14 2022 at 21:46):
Exactly
Mario Carneiro (Feb 14 2022 at 21:46):
You can write your own print axioms though
Matthew Ballard (Feb 14 2022 at 21:46):
But you can probably filter the environment for constants
Mario Carneiro (Feb 14 2022 at 21:46):
I have a code snippet for that lying around somewhere
Matthew Ballard (Feb 14 2022 at 21:47):
If you want to drop when you find it, I would appreciate it
Matthew Ballard (Feb 14 2022 at 21:47):
I also wrote something that filters the environment by directory to read from a student's assignment
Mario Carneiro (Feb 14 2022 at 21:48):
Matthew Ballard (Feb 14 2022 at 21:48):
So I imagine it is not far from there to filter by constant
Matthew Ballard (Feb 14 2022 at 21:48):
Thanks
Jason Rute (Feb 14 2022 at 21:51):
Do you know about lean --json
? It makes the output into a json stream and makes it easier to work with the output programmatically.
Matthew Ballard (Feb 14 2022 at 21:51):
Eric Wieser said:
I'm not sure about the attribute, but those meta defs look worth PRing to me
I echo this sentiment
Matthew Ballard (Feb 14 2022 at 21:52):
I know about the existence of lean --json
but not much more. I should take a look
Matthew Ballard (Feb 14 2022 at 21:54):
Is it easy to understand what the keys are for the json stream?
Jason Rute (Feb 14 2022 at 21:55):
I think it is self explanatory, but not documented, if that makes sense.
Matthew Ballard (Feb 14 2022 at 21:56):
I can dump some stuff and learn
Henrik Böving (Feb 14 2022 at 22:46):
Matthew Ballard said:
I would have thought errors and warnings would get pushed to
stderr
There are pretty standard tools that do print their trace to stderr, for example strace
does so because the main program might be busy printing to stdout while it's spying on it. I think you can make an argument that it makes sense for the "tracing" and the "regular stdout" stream to be different because then you can, pipe/grep/whatever exactly the stream you want right in your shell instead of having to somehow split them up again.
Henrik Böving (Feb 14 2022 at 22:46):
At least that's how I've always used this eh "feature" of strace.
Matthew Ballard (Feb 15 2022 at 13:28):
Ok. I think I have better mental model. If I assume Lean’s purpose is telling you when your proof is correct/incorrect then warnings/errors go to the usual placestdout
. Less relevant output gets piped to stderr
to avoid clutter.
Last updated: Dec 20 2023 at 11:08 UTC