Section 5.3

Only a call stands alone

A statement that computes a value and throws it away is refused — and that refusal closes the last shape of the = trap.

Now that a call can return a value, we must say which ones are allowed to take a line to themselves. The answer is short: very few.

@entry(start)
object MyProgram {
    start() {
        var total := 12;

        self.announce(value: total);

        total := total + 5;
        self.announce(value: total);
    }

    announce(value: int) {
        Console.print(text: $"total: {value}");
    }
}

Three kinds of statement, and nothing else. self.announce(…) is a call; total := total + 5 is an assignment; an increment, total++, would be a third.

Computing and discarding is an error

Write a line that is only an expression — it computes a value nobody receives:

error[D023]: this statement has no effect: its value is computed and thrown away.
Only a call stands alone as a statement. If you meant to assign, the operator is ':=' — '=' compares

total + 1; computes 18 and abandons it at once. Nothing in the program changed, no trace of it remains: the line had no effect, and the compiler would rather tell you than build it.

Only a call has a reason to stand alone, since it alone acts: it can print, write, modify. Whether you keep what it returns is your business.

What the rule really protects

Read the end of the diagnostic again: If you meant to assign, the operator is ':=' — '=' compares.

Section 3.1 took away half of the costliest trap in the C family: if (x = 5) does not exist here, because a condition must be a bool and an assignment is not one. The other half remained — the lone line. Without this rule, total = 5; would be legal and silent code: a comparison written by someone who meant to assign, whose result goes in the bin, and which nothing flags.

That last shape is what D023 closes. The mistake now has no form left to be written in.

Your turn

  • Replace total := total + 5; with total = 5; and read the diagnostic. One letter apart, and the compiler sees exactly what you meant to do.
  • Try total + 1;, then total; on its own. Same refusal: neither one acts.
  • Replace the line with self.announce(value: total + 5);. The addition is still there, but it feeds a call instead of falling into the void — and the last line prints 12 again, since nothing was stored in total. Computing and keeping are two distinct gestures.