println writes a line to the host runtime’s standard output. It is the output
function used throughout this book.
fn main(): void {
println("hello")
}It takes exactly one string, so values are formatted before the call — most
often with interpolation:
fn main(): void {
name := "ada"
count := 3
println("${name} has ${count} items")
}Concatenation works too, but every operand must already be a string:
fn main(): void {
n := 42
println("n = " + n.to_string())
}Interpolation uses Display
"${value}" calls the value’s to_string through the
Display trait, so implementing
Display makes a user type printable:
struct Point { x: int, y: int }
impl Display for Point {
fn to_string(self): string => "(${self.x}, ${self.y})"
}
fn main(): void {
println("${Point { x: 1, y: 2 }}")
}A nested " inside an interpolation hole is not supported — bind the string to
a local first rather than escaping it.
println is a suspending call
This is the surprising part, and it explains diagnostics you will meet early.
println is declared @host("atoll_runtime::io", "println") @suspend, so
any function that calls it acquires the Suspend effect, and so does every
caller above it.
The annotation is about which ABI the call lowers to, not about latency: the host handler completes inline and never waits on the event loop, but it hands the continuation back through the suspending ABI. (Omitting it was historically a silent miscompile — a caller lowered as non-suspending around a suspending call lost its return value.)
You do not write that effect down. Effects are inferred, and ordinary Atoll
code simply calls println:
fn report(total: int): void {
println("total=${total}")
}
fn main(): void {
report(7)
}That program compiles and runs. It also emits a warning, and this is the part worth internalising early:
warning[ATOLL2032]: fn `report` inherits effect `suspend` from a
transitively-called callee but its declared `using [..]` row does not list
`suspend`ATOLL2032 is noise here — leave it. The diagnostic suggests declaring an
effect row, but effect rows are an explicit-contract feature that real Atoll
code essentially never writes; there is not one in the compiler’s own sample
projects or prelude. Nothing about the program is wrong, and the warning does
not stop compilation. See Effects for when a
row is genuinely worth writing.
Keep println out of a function you want to stay non-suspending — a pure
computation should return its value and let the caller print it:
fn double(x: int): int {
return x * 2
}
fn main(): void {
println("${double(21)}")
}Capability and redirection
println routes through the host boundary rather than writing directly, which
has two consequences:
- A sandboxed deployment can deny the
atoll_runtime::iocapability, and thenprintlncalls fail at load rather than silently doing nothing. - An embedder can divert output into a buffer instead of the process’s stdout, which is how the runtime’s tests capture program output.
There is no print without a newline, no formatted-print variant, and no
prelude logger. Build the complete line as a string and pass it.