Wiki

Clone wiki

helium / popl20 / Tutorial_Basics

Tutorial 1: Basics

We describe the basic syntax, mostly by example. Helium is heavily inspired by OCaml and SML, so the reader familiar with any of those should feel comfortable with the language right away.

Functions

Functions can be defined using let definitions:

let commaSep a b = a ++ "," ++ b
Recursive functions must be explicitly marked as such.
let rec fact n =
  if n = 0
    then 1
    else n * fact (n - 1)
Mutually recursive functions are also allowed.
let rec even n =
  if n = 0
    then True
    else odd (n - 1)
and odd n =
  if n = 0
    then False
    else even (n - 1)
Use the fn keyword to create an anonymous function. Such definitions are ordinary expressions, so they can be passed as arguments to other functions.
[IO,RE]> import List;;
[IO,RE]> List.map (fn x => x > 1) [1, 2, 3];;
[False,True,True] : List Bool

Pattern matching and data types

Helium's standard library provides several useful algebraic data types, such as Option or List. Elements of such types can be inspected by pattern matching, not different from other languages:

let rec optMap f xs =
  match xs with
  | []      => []
  | x :: xs =>
    match f x with
    | None   => optMap f xs
    | Some y => y :: optMap f xs
    end
  end
We can also define our own data types using the data keyword.
data Color = Red | Green | Blue | RGB of Int, Int, Int
Recursive and mutually recursive data types must be explicitly marked with the rec keyword. Types can be parametrized.
data rec Tree (X : Type) =
  | Leaf
  | Node of Children X
and data Children (X : Type) =
  | Child of Tree X
  | Cons  of Tree X, X, Children X

Local definitions

Expressions at the lowest precedence level can start with a list of definitions followed by the in keyword and another expression. This allows us to define local (recursive) functions, values, data types, effects, and modules. It is also useful for opening a module locally.

import List

let foo xs =
  data T = T of Bool, Int
  let bar (T b n) = if b then n else -n
  open List
  let ys = map (fn x => T (x > 0) x) xs
  in
  map bar ys

Updated