Examples

The following examples work entirely in Stella Core, without any extensions, and can be used to test implementations of the language.

Factorial

language core;

// a constant function, specialized to Nat
fn Nat2Nat::const(f : fn(Nat) -> Nat) -> (fn(Nat) -> (fn(Nat) -> Nat)) {
  return fn(x : Nat) { return f }
}

// addition of natural numbers
fn Nat::add(n : Nat) -> (fn(Nat) -> Nat) {
  return fn(m : Nat) {
    return Nat::rec(n, m, fn(i : Nat) {
      return fn(r : Nat) { return succ(r) } })
  }
}

// multiplication of natural numbers
fn Nat::mul(n : Nat) -> (fn(Nat) -> Nat) {
  return fn(m : Nat) {
    return Nat::rec(n, 0, Nat2Nat::const(Nat::add(m)))
  }
}

// factorial via primitive recursion
fn factorial(n : Nat) -> Nat {
  return Nat::rec(n, succ(0), fn(i : Nat) {
    return fn(r : Nat) {
    return Nat::mul(r)(succ(i))  // r := r * (i + 1)
  } })
}

fn main(n : Nat) -> Nat {
  return factorial(n)
}

Square Numbers

language core;

// addition of natural numbers
fn Nat::add(n : Nat) -> fn(Nat) -> Nat {
  return fn(m : Nat) {
    return Nat::rec(n, m, fn(i : Nat) {
      return fn(r : Nat) {
        return succ( r ) // r := r + 1
      }
    })
  }
}

// square, computed as a sum of odd numbers
fn square(n : Nat) -> Nat {
  return Nat::rec(n, 0, fn(i : Nat) {
      return fn(r : Nat) {
        // r := r + (2*i + 1)
        return Nat::add(i)( Nat::add(i)( succ( r )))
      }
  })
}

fn main(n : Nat) -> Nat {
  return square(n)
}

Logical Operations

language core;

// logical operator not
fn Bool::not(b : Bool) -> Bool {
  return if b then false else true
}

// logical operator or
fn Bool::or(a : Bool) -> (fn(Bool) -> Bool) {
  return fn(b : Bool) {
    return if a then true else b
  }
}

// logical operator and
fn Bool::and(a : Bool) -> (fn(Bool)->Bool) {
  return fn(b : Bool) {
    return if a then b else false
  }
}

// logical operator xor
fn Bool::xor(a : Bool) -> (fn(Bool)->Bool) {
  return fn(b : Bool) {
    return
        Bool::or(Bool::and(a)(Bool::not(b)))(Bool::and(Bool::not(a))(b))
  }
}


fn main(n : Bool) -> Bool {
  return Bool::xor
    (Bool::and  // always false
      (n)
      (Bool::not(n)))
    (Bool::or   // always true
      (Bool::not(n))
      (n))
}