Chapter 2: Making decisions

Tracks on tracks on tracks

  • lists
  • multi-clause functions

[language | languages] builds a new list with one more item at the front. The same shape works as a pattern, which is how count_languages walks a list.

This is the first multi-clause function. The body-less line declares the types once. Then each def handles one shape of input: the empty list, or a list with a head and a tail. Bea joins the clauses into a single Gleam function with a case, so the recursion stays tail-call optimised.

Open in playground
def new() {
  []
}

def existing() -> List(String) {
  ["Bea", "Gleam", "Go", "Rust"]
}

def add_language(languages: List(String), language: String) -> List(String) {
  [language | languages]
}

def count_languages(languages: List(String), sum: Int) -> Int

def count_languages([], sum) {
  sum
}

def count_languages([_ | tail], sum) {
  count_languages(tail, sum + 1)
}

pub def main() {
  echo new()
  echo existing()
  echo add_language(["OCaml", "Gleam"], "Bea")
  echo count_languages(["jq", "Elm", "Rust", "Kotlin"], 0)
}

An exercism exercise from the Gleam track, solved in Bea: beacode/src/e7_tracks_on_tracks.bea