# EX Script — Example Applications

These are real, runnable programs — they exist in `examples/` and are executed
by the test suite.

## 1. Hello world

```
// examples/hello/src/main.xan
import std.io

export fun main() {
    io.println("Hello, world!")
}
```

## 2. CLI tool: argument parsing + env + exit codes

```
// examples/cli/src/main.xan
import std.io
import std.cli
import std.env

export fun main(args: List<String>) -> Int {
    let cmd = cli.parse(args, cli.spec()
        .flag("--verbose")
        .positional("name", required: true))
    let name = cmd.get("name").require("name is required")
    let who = env.get("WHO") or name
    io.println("hi {who}" + if cmd.has("--verbose") { " (verbose)" } else { "" })
    0
}
```

## 3. HTTP server with schema validation

```
// examples/server/src/main.xan
import std.io
import std.http
import std.json

schema NewUser {
    name: String (minLen: 1, maxLen: 100)
    email: Email
    age: Int (min: 0)
}

export async fun main() {
    http.serve(8080, fun (req: http.Request) -> http.Response {
        match req.path {
            "/health" -> http.ok("{}")
            "/users" -> handleUsers(req)
            _ -> http.notFound()
        }
    })
    io.println("listening on :8080")
}

fun handleUsers(req: http.Request) -> http.Response {
    match req.method {
        "POST" -> {
            let body = req.text() or "{}"
            match NewUser.parse(body) {
                Ok(user) -> http.json(http.stringify(user))
                Err(e) -> http.badRequest(e.message)
            }
        }
        _ -> http.methodNotAllowed()
    }
}
```

## 4. Concurrency: parallel fetch with structured results

```
// examples/concurrency/src/main.xan
import std.io
import std.http

async fun fetchTitle(url: String) -> String! {
    let res = await http.get(url)?
    let html = res.text() or ""
    html.xantract("<title>(.*?)</title>") or "untitled"
}

export async fun main() {
    let urls = ["https://example.com", "https://example.org"]
    let (a, b) = await all(fetchTitle(urls[0]), fetchTitle(urls[1]))
    io.println("a: {a}")
    io.println("b: {b}")

    let winner = await race(fetchTitle(urls[0]), fetchTitle(urls[1]))
    io.println("first: {winner or "no title"}")
}
```

## 5. Data processing: ADTs + pattern matching

```
// examples/shapes/src/main.xan
import std.io

type Shape =
    | Circle(radius: Float)
    | Square(side: Float)
    | Rect(width: Float, height: Float)

fun area(s: Shape) -> Float {
    match s {
        Circle(r) -> 3.14159 * r * r
        Square(side) -> side * side
        Rect(w, h) -> w * h
    }
}

test "circle area" {
    expect(area(Circle(1.0))).approx(3.14159)
}

test "rect area" {
    expect(area(Rect(2.0, 3.0))).eq(6.0)
}
```

## 6. Error handling: Result composition

```
// examples/errors/src/main.xan
import std.io

fun parsePort(s: String) -> Int {
    let n = Int.parse(s)?
    if n < 1 or n > 65535 { raise "port {n} out of range" }
    n
}

fun start(portText: String) -> String! {
    let port = parsePort(portText)?
    "starting on :{port}"
}

export fun main() {
    match start("8080") {
        Ok(msg) -> io.println(msg)
        Err(e) -> io.println("failed: {e}")
    }
}
```

## 7. Testing a library

```
// examples/mathlib/src/main.xan
export fun fib(n: Int) -> Int {
    match n {
        0 -> 0
        1 -> 1
        _ -> fib(n - 1) + fib(n - 2)
    }
}

test "fibonacci" {
    expect(fib(0)).eq(0)
    expect(fib(1)).eq(1)
    expect(fib(10)).eq(55)
}

async test "math is async-safe" {
    let x = await async fun () -> Int { fib(6) }()
    expect(x).eq(8)
}
```

## 8. Schema round-trip (runtime validation)

```
// examples/schema/src/main.xan
import std.io
import std.json

schema Config {
    port: Int (min: 1, max: 65535, default: 3000)
    debug: Bool (default: false)
    tags: List<String> (default: [])
}

export fun main() {
    let raw = """{"port": 99999}"""
    match Config.parse(raw) {
        Ok(c) -> io.println("ok: {c.port}")
        Err(e) -> io.println("rejected: {e.message}")
    }
}
```

Every example runs under `ex test`; the fixture suite in `tests/fixtures/`
covers the compiler itself (parse/check/codegen + runtime behavior).