Zulip Chat Archive
Stream: lean4
Topic: Print from Rust
Marcus Rossel (Sep 09 2024 at 13:40):
If I run the following Rust function from Lean, it prints "Hello"
to stdout:
fn printhello() {
println!("Hello");
}
But if the function never returns, it never prints "Hello"
as in the following:
fn nohello() {
println!("Hello");
loop {};
}
Is there a way to get nohello
to print to stdout anyway?
#xy: I'm trying to print-debug from Rust. I think I have a non-terminating loop somewhere, and am trying to figure out where.
Alex J. Best (Sep 09 2024 at 13:52):
Do you need to flush stdout maybe on the rust side. Seems strange that it wouldn't print at all, more likely that it's just buffered
Marcus Rossel (Sep 09 2024 at 13:54):
@Alex J. Best I tried using io::stdout().flush()
, but that didn't help.
Julian Berman (Sep 09 2024 at 14:03):
(I thought maybe so too, but Rust appears to still use line-buffering always according to https://github.com/rust-lang/rust/issues/60673 )
Julian Berman (Sep 09 2024 at 14:04):
If you strace do you see the syscall happen maybe?
Eric Wieser (Sep 09 2024 at 14:06):
How are you calling rust from Lean?
Marcus Rossel (Sep 09 2024 at 14:08):
Eric Wieser said:
How are you calling rust from Lean?
I should have mentioned that! It's as part of a tactic - so at compile time in MetaM
.
Eric Wieser (Sep 09 2024 at 14:10):
So it's linked via extern
, not run via a subprocess?
Marcus Rossel (Sep 09 2024 at 14:12):
Eric Wieser said:
So it's linked via
extern
, not run via a subprocess?
Exactly! (I'm setting up an mwe repo as we speak)
Mauricio Collares (Sep 09 2024 at 14:13):
(regarding the #xy-question, perhaps it would be useful to gdb attach
to your process)
Marcus Rossel (Sep 09 2024 at 14:44):
Ok, here's a #mwe repo: https://github.com/marcusrossel/mwe/tree/main
But for some reason, right now it's not even printing "hello"
/looping for the following:
import Lean
open Lean Meta Elab Tactic
@[extern "lean_printhello"]
opaque printhello : Unit → Unit
@[extern "lean_nohello"]
opaque nohello : Unit → Unit
def Unit.toExpr (_ : Unit) : MetaM Expr :=
Lean.Meta.mkAppM ``Unit.unit #[]
elab "hello" : tactic => do
let u := printhello ()
(← getMainGoal).assign (← u.toExpr)
example : Unit := by
hello
elab "nohello" : tactic => do
let u := nohello ()
(← getMainGoal).assign (← u.toExpr)
example : Unit := by
nohello
(I added the Unit.toExpr
dance in the hope that it would mean that Lean doesn't optimize away the calls to printhello
and nohello
- though I have no clue if that's necessary or effective.)
Tomas Skrivan (Sep 09 2024 at 16:18):
Does it work as expected if printhello
and nohello
live in IO
monad?
Tomas Skrivan (Sep 09 2024 at 16:20):
I don't think that u.toExpr
is preventing Lean from optimizing the calls away.
Kyle Miller (Sep 09 2024 at 17:04):
If it's not in the IO monad, I think the reliability of printing is more like dbg_trace
, which will happen if it's forced to, but it might be eliminated. For example, I don't see any messages in
def printHello : Unit → Unit := fun _ => dbg_trace "hello"; ()
#eval printHello ()
Leni Aniva (Sep 09 2024 at 18:31):
Does it work if you print to stderr instead to remove the buffering?
Marcus Rossel (Sep 11 2024 at 16:43):
Leni Aniva said:
Does it work if you print to stderr instead to remove the buffering?
Using eprintln!
didn't work either.
Marcus Rossel (Sep 11 2024 at 16:53):
Kyle Miller said:
If it's not in the IO monad, I think the reliability of printing is more like
dbg_trace
I tried wrapping my function's return type in IO
and using lean_io_result_mk_ok
when returning the result from C. Should that be enough to see println!
s? Because when the Rust function is non-terminating I still don't see the result of the println!
.
Last updated: May 02 2025 at 03:31 UTC