A program writes formatted text onto its two output streams with four words of the unit std:

WordStreamEnds its text with a newline
WriteLnstandard outputyes
Writestandard outputno
WriteErrLnstandard erroryes
WriteErrstandard errorno

Standard output carries what a program answers, and standard error what it says about its own run, so a pipeline or a parent that reads the answer never mistakes a diagnostic for part of it:

cat > check.mica << 'EOF'
program Check;

imp
    WriteLn, WriteErrLn : std;
    ArgCount, Arg, Halt : process;

begin
    if ArgCount() < 1 then
    begin
        WriteErrLn("check: name the file to check");
        Halt(2);
    end;

    WriteLn("checking %ls", Arg(1));
end.
EOF

mica --run check.mica
check: name the file to check

That line is on standard error, and the run ends with status 2. Named a file, the program answers on standard output:

mica --run check.mica notes.txt
checking notes.txt

The format

All four words take the same format: a string literal or a named string constant, then one argument for each conversion it holds. The conversions are C’s, %lld for an int64, %lf for a float64, and the string conversion of the build’s encoding, which the type system names. The compiler checks every conversion against its argument and refuses a mismatch by name; here count is an int32:

WriteErrLn("%d of %d", count);
WriteErrLn("%lld", count);
analyzer error 5183: format string parameter count mismatch: expected 2 format specifiers, got 1 arguments
analyzer error 5184: format string validation error: format specifier '%lld' at position 1 incompatible with type: int32

One line, one write

Each call hands its whole text to the stream at once, its newline included. The lines that tasks on several carriers write at the same moment therefore arrive whole, one after the other, and never spliced into each other.

Standard output is written line by line on a terminal, and in blocks of about 4 KiB to a pipe or a file, so the reader of a pipe sees the text when a block fills or the program ends; the runtime flag stdout=line writes every line through as it is written. Standard error keeps no buffer: each call reaches the stream at once.

When a stream stops taking text

A reader that has gone

When standard output or standard error is a pipe and the program at its other end has closed it, the program ends at its next write to that stream, by the signal SIGPIPE, as every program in a pipeline is expected to: a pipeline stops as soon as its last reader has what it wanted. A shell reports the status 141:

cat > count.mica << 'EOF'
program Count;

imp
    WriteLn : std;

var
    i : int64;

begin
    i := 0;

    while True do
    begin
        i := i + 1;
        WriteLn("%lld", i);
    end;
end.
EOF

mica --run count.mica | head -3
echo "${PIPESTATUS[0]}"
1
2
3
141

Text that still waits in standard output’s buffer when the program ends meets the vanished reader in the flush that hands it over, and the program ends by SIGPIPE there.

Any other lost write

A full device, an input or output error, or a closed descriptor loses the text while the program goes on, because only the program’s end can say that its output is incomplete. When the program ends, it writes one line on standard error naming the stream and the reason, and an exit status of 0 becomes 1, so a script or a parent never reads success from a program whose output was lost:

cat > hello.mica << 'EOF'
program Hello;

imp
    WriteLn : std;

begin
    WriteLn("hello");
end.
EOF

mica --run hello.mica > /dev/full
echo "$?"
Mica output report: standard output lost text the program wrote to it (No space left on device)
1

The reason is the operating system’s own description of the failure. A status the program chose itself with Halt stays the program’s, and the line still says what was lost. When standard error is the stream that lost text, the line is lost with the rest, and the status still says 1.

The streams as values

The files unit’s StdOut() and StdErr() answer the same two streams as values, and every write through them reports its failure on the failure channel instead: WriteLine fails with an OsError, Epipe when the reader has gone, and the program decides what happens next. Both rules above belong to the four words of std alone.