Chapters

Functions and Control Flow

Combine computations and branch according to conditions.

4.1 Define functions

Define functions with fn. Give types to parameters and results; the last expression supplies the result.

ch04-fn.taut
fn double(x: i64): i64 {
  x * 2
}

fn add(a: i64, b: i64): i64 {
  a + b
}

let result := add(double(4), 3)
perform show("result", result)

// Compose double and add to compute eleven.
Execution result
・ double
・ add

result = 11
result = 11

Use return to exit early. In short functions, using the final expression as the result is often easier to read.

ch04-return.taut
fn early(x: i64): i64 {
  if x < 0 { return 0 }
  x
}

perform show("early", early(-3))

// Return early for negative inputs.
Execution result
・ early

early = 0
early = 0

4.2 if is an expression

ch04-if.taut
fn absolute(x: i64): i64 {
  if x < 0 { 0 - x } else { x }
}

let n := absolute(-12)
perform show("absolute", n)

// Both branches return the absolute value.
Execution result
・ absolute

absolute = 12
absolute = 12

Both branches of if return a value, which an enclosing expression can use. This composes expressions rather than merely splitting execution into paths.

4.3 Functions are values too

Write a lambda (an anonymous function) as x => expression.

ch04-lambda.taut
fn twice(f: (i64) -> i64, x: i64): i64 {
  f(f(x))
}

let result := twice(x => x + 10, 1)
perform show("twice", result)

// Pass a function as data and apply it twice.
Execution result
・ twice

twice = 21
twice = 21

The function type (i64) -> i64 accepts an i64 and returns an i64. twice takes a function as an argument and calls it twice.

4.4 Loops and termination

ch04-while.taut
var i: i64 := 0
var sum: i64 := 0
while i < 4 {
  sum := sum + i
  i := i + 1
}
perform show("sum", sum)

// Accumulate zero through three with a mutable loop.
Execution result
sum = 6
sum = 6

while is associated with the effect Div, meaning that evaluation may not terminate. This particular loop finishes because i increases, but an arbitrary while loop may run forever. Tauto reflects that possibility in types and effects. Chapter 15 covers well-founded recursion when you need a termination proof.

Exercise 4.1: Write maximum(a: i64, b: i64) -> i64 using an if expression.