# 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`

```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:

```text
== 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:

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

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

`xo check` says:

```text
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)
```


