Xo is experimental. The source code is not public yet; it will be soon. Read the release notes
Menu · Effects and capabilities

Docs

Effects and capabilities

In Xo, a function’s signature says what it can touch. The effects are net, fs, clock, rand, env, proc, and stdio. A pub function declares the ones it uses; one without a uses clause is pure.

effects/main.xo

pub fn banner(out: Stdio, name: Str) uses stdio {
  out.println("== ${name} ==")
}

pub fn slugify(s: Str) -> Str {
  s.trim().to_lower().replace(" ", "-")
}

fn main(os: Os) {
  banner(os.stdio, slugify("  Hello World "))
}

test "banner prints the name" {
  banner(os.stdio, "x")
  expect(os.stdio.output()) == "== x ==\n"
}

Output:

== hello-world ==
  • banner declares uses stdio; slugify declares nothing, so it cannot touch the outside world at all.
  • The authority itself is a value: banner can only print because it was handed a Stdio. The only source of these capabilities is main’s os, so a library cannot open a file or a socket unless someone gives it one.
  • In a test, os holds fakes: an in memory filesystem, a virtual clock, a network that fails unless you register a handler, and captured output, as os.stdio.output() shows.

Forgetting to declare an effect is caught, with the call that performs it:

pub fn greet(out: Stdio, name: Str) {
  out.println("hello, ${name}")
}

fn main(os: Os) { greet(os.stdio, "Ada") }

xo check says:

main.xo:1:8: error XO0701: `greet` is pub with no `uses` clause, so it is pure, but performs `stdio`
  note: main.xo:2:3: `Stdio.println` uses `stdio` here
1 module(s), 1 error(s), 0 warning(s)