Let's start with the fundamental capabilities one might find in almost any program. To keep it simple, we focus first on how to read and write programs that work with numbers, such as this one which calculates the value of pi:

import stdio::*

fn main():
  imm pi = calcpi(10)
  print <- "\u03C0=", calcpi(10), "\n" // <-- Change 10 to 2 for less accurate pi

// Calculate pi using arc-sine fractional sequence.
// 'nterms' is the number of fractional terms used to estimate pi
// https://en.wikipedia.org/wiki/Approximations_of_%CF%80#Arcsine
fn calcpi(mut nterms = 10) f64:
  if nterms <= 0:
    return 0d
  
  // Initialize working values
  mut result = 0.5d
  mut seed = 1d
  mut top = 1d
  mut bot = 1d
  mut twos = 2d
  mut term = 0d
  
  while --nterms:
    // Calc a new fraction and add to result
    top *= seed
    bot *= seed + 1d
    twos *= 2d * 2d
    term = top / (bot * (seed + 2d) * twos)
    result += term
    seed += 2d
  result * 6d

Over the next few pages, the story will unfold in this way: We begin by introducing the primitive values: numbers and variables. Using these values and various operators, we can then form expressions that calculate new values. Multiple expressions and other statements can then be assembled into a block, which evaluates its statements in order. One or more blocks can define the logic of a function.

Let's get started!

_