Section 5.1

Returning a value

An arrow, a return, and a call stops being a mere action to become a value.

A method can hand a value back to whoever called it. It needs two things: to say of what type, and to hand it over.

@entry(start)
object MyProgram {
    start() {
        var largest := self.maximum(a: 12, b: 7);

        Console.print(text: $"the largest: {largest}");
        Console.print(text: $"and between 3 and 9: {self.maximum(a: 3, b: 9)}");
    }

    maximum(a: int, b: int) -> int {
        if (a > b) {
            return a;
        }

        return b;
    }
}

The arrow announces, return delivers

maximum(a: int, b: int) -> int {

The arrow -> follows the parameter list and announces the type of what the method will return. Here an int — the type section 2.3 recommends when you simply want an integer.

return delivers the value and leaves the method on the spot. What follows in the body is not run. That is why maximum needs no else: if a > b holds, the first return leaves with a and the last line is never reached.

A method with no arrow returns nothing, which is the case of every one written so far — start, greet. Nothing changes for them. return is still allowed there, alone and without a value: it then serves to leave early.

The call becomes a value

This is the real change. Until now a call could only act; it took a line to itself and that was all. A call that returns a value goes wherever a value goes:

var largest := self.maximum(a: 12, b: 7);
Console.print(text: $"and between 3 and 9: {self.maximum(a: 3, b: 9)}");

To the right of a :=, in an interpolated hole, as the argument of another call. The program can at last compute somewhere other than in start and bring the result back.

There is no free function

A method is declared inside an object, never alone at file level. That is why maximum is written in MyProgram, within the same braces as start, and why start calls it as self.maximum(…) — self names the object itself, as section 1.2.1 noted in passing.

No keyword declares a method: a name, parameters in parentheses, the arrow where there is one, a body. That is all that sets it apart from the rest.

Your turn

  • Change the first call to a: 12, b: 70: the answer follows, without maximum being touched.
  • Slip Console.print(text: "never"); right after the first return. The program runs and shows nothing new — but the compiler will not let you believe that line counts: warning[W002]: unreachable statement: the previous one leaves the block.
  • Write a method double(value: int) -> int returning value * 2, and print self.double(value: self.maximum(a: 12, b: 7)) — 24. A call that returns a value can feed another call.