'print()' should be async because it does IO. In the real world most likely you'd see the output once you yield.
'print()' should be async because it does IO. In the real world most likely you'd see the output once you yield.
Normally print isn’t a debug message function, people just use it like that. (it normally works on non debug builds)
If your console app is writing output to any device, it must, for instance, handle errors gracefully.
That means, at least in Rust, write! rather than print!.
From the docs: "Use println! only for the primary output of your program. Use eprintln! instead to print error and progress messages."
There is no point in juggling around Result types if a failure means that you can not recover/continue execution. That is in fact exactly what panic! is intended for [1].
[1]: https://doc.rust-lang.org/book/ch09-03-to-panic-or-not-to-pa...
You can and should recover from bog standard IO failures in production code, and in any case you'd better not be panicking in library code without making it really clear that it's justified in the docs.
If your app crashes in flames on predictable issues it's not a good sign that it handles the unpredictable ones very well.
Now if you fail to write to stderr, yeah, that's a good reason for a console app to panic. The onus is on the user to provide something that is "good enough" in that case.
IMO the real problem is that print() etc defaults to stdout historically, but is used mostly for diagnostic information rather than actual output in practice, so it should really go to stderr instead. This would also take care of various issues with buffering etc.
There's value in the Hello, World and println-debugging style print, even if it should be eschewed in most general contexts.
Consider something as trivial as `cat foo >readonly_file` to see why.
I personally find myself using print debugging as a last resort when the debugger doesn't suffice.
What if I want to do synchronous IO?
> Dada, like JavaScript, is based exclusively on async-await. This means that operations that perform I/O, like print, don't execute immediately. Instead, they return a thunk, which is basically "code waiting to run" (but not running yet). The thunk doesn't execute until you await it by using the .await operation.
Good riddance, IMO — never been a fan of blocking IO. Dada does have threads though, so I wonder how that works out. (Forcing async/await makes a lot more sense in JavaScript because it's single-threaded.)
What you're asking for is "stop running my code until I've finished printing to the console". That's what the `.await` does. Synchronous IO on `print()` would mean _everything in the whole application that logs_ suddenly blocks the whole application from doing _anything_ while the console is being written to, not just the currently running code.
If you want synchronous stop-the-world IO (like Python, where async/await is bolted on), you shouldn't choose a language based around async/await concurrency.
.NET core will introduce something similar
JavaScript lets you do it much more ergonomically.
let f = spawn { print() } // fork
...
wait f // join. f is a linear type
You only pay the complexity cost if you need it.