# Vary Course

## Vary Language Tour

Twelve runnable lessons covering typed values, functions, data, state, enums, dictionaries, nullable values, modules, and tests.

### Values, functions, control flow

#### Values and types

Bind typed values and print a release string.

```vary
let project: Str = "acme-billing"
let major: Int = 2
let minor: Int = 14

print(project + " v" + str(major) + "." + str(minor))

```

Run: `vary run main.vary`

Expected output:

```text
acme-billing v2.14
```

#### Functions and branches

Classify an HTTP status with a pure helper.

```vary
pure def class_of(status: Int) -> Str {
    if status >= 500 {
        return "5xx"
    }
    if status >= 400 {
        return "4xx"
    }
    if status >= 200 {
        return "2xx"
    }
    return "other"
}

print("404 -> " + class_of(404))

```

Run: `vary run main.vary`

Expected output:

```text
404 -> 4xx
```

#### Lists and loops

Count how many requests exceeded a latency budget.

```vary
let durations_ms: List[Int] = [42, 180, 95, 240, 33]
mut slow: Int = 0

for d in durations_ms {
    if d > 100 {
        slow = slow + 1
    }
}

print("slow=" + str(slow))

```

Run: `vary run main.vary`

Expected output:

```text
slow=2
```

### Modeling data

#### Data types

Define an immutable record and read its generated `toString`.

```vary
data Response {
    status: Int
    bytes: Int
}

let resp = Response(200, 1024)
print(str(resp))

```

Run: `vary run main.vary`

Expected output:

```text
Response(status=200, bytes=1024)
```

#### Classes and state

Track remaining retries behind a small stateful class.

```vary
class RetryBudget(max: Int) {
    mut remaining: Int = max

    def consume(self) -> None {
        self.remaining = self.remaining - 1
    }

    def left(self) -> Int {
        return self.remaining
    }
}

let budget = RetryBudget(3)
budget.consume()
print("remaining=" + str(budget.left()))

```

Run: `vary run main.vary`

Expected output:

```text
remaining=2
```

#### Enums and exhaustive match

Advance a build state machine with exhaustive matching.

```vary
enum BuildState {
    QUEUED
    RUNNING
    PASSED
    FAILED
}

pure def advance(state: BuildState) -> BuildState {
    match state {
        case BuildState.QUEUED {
            return BuildState.RUNNING
        }
        case BuildState.RUNNING {
            return BuildState.PASSED
        }
        case BuildState.PASSED {
            return BuildState.PASSED
        }
        case BuildState.FAILED {
            return BuildState.FAILED
        }
    }
}

print(str(advance(BuildState.QUEUED)))

```

Run: `vary run main.vary`

Expected output:

```text
RUNNING
```

#### Nullable values

Fall back to a default when a configured value is missing.

```vary
let configured: Int? = None
mut port: Int = 8080

if configured is not None {
    port = configured
}

print("port=" + str(port))

```

Run: `vary run main.vary`

Expected output:

```text
port=8080
```

### Lookups and modules

#### Typed maps

Look up a service timeout from a config map.

```vary
let timeouts: Dict[Str, Int] = {"db": 30, "http": 10, "cache": 60}

print("http=" + str(timeouts["http"]) + "s")

```

Run: `vary run main.vary`

Expected output:

```text
http=10s
```

#### Module-ready helpers

Format an artifact coordinate with a pure helper.

```vary
pure def coord(group: Str, name: Str, version: Str) -> Str {
    return group + ":" + name + ":" + version
}

print(coord("acme", "billing", "1.4.2"))

```

Run: `vary run main.vary`

Expected output:

```text
acme:billing:1.4.2
```

### Tests

#### Shape helpers for assertion

Print the inputs and outputs the next lesson will assert on.

```vary
pure def class_of(status: Int) -> Str {
    if status >= 500 {
        return "5xx"
    }
    if status >= 400 {
        return "4xx"
    }
    return "2xx"
}

print(class_of(503) + "," + class_of(200))

```

Run: `vary run main.vary`

Expected output:

```text
5xx,2xx
```

#### Run passing assertions

Run two `observe` assertions against the helper.

```vary
pure def class_of(status: Int) -> Str {
    if status >= 500 {
        return "5xx"
    }
    if status >= 400 {
        return "4xx"
    }
    return "2xx"
}

test "server errors classify as 5xx" {
    observe class_of(503) == "5xx"
}

test "client errors classify as 4xx" {
    observe class_of(404) == "4xx"
}

```

Run: `vary test tests/grade_test.vary`

Expected output:

```text
Results: 2 passed, 0 failed
```

#### Read a failing test

Run a file with one intentional boundary mistake and find the summary line.

```vary
pure def class_of(status: Int) -> Str {
    if status >= 500 {
        return "5xx"
    }
    if status >= 400 {
        return "4xx"
    }
    return "2xx"
}

test "server errors classify as 5xx" {
    observe class_of(503) == "5xx"
}

test "boundary 500 should be 4xx" {
    observe class_of(500) == "4xx"
}

```

Run: `vary test tests/grade_test.vary`

Expected output:

```text
Results: 1 passed, 1 failed
```

