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.

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:

acme-billing v2.14

Functions and branches

Classify an HTTP status with a pure helper.

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:

404 -> 4xx

Lists and loops

Count how many requests exceeded a latency budget.

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:

slow=2

Modeling data

Data types

Define an immutable record and read its generated toString.

data Response {
    status: Int
    bytes: Int
}

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

Run: vary run main.vary

Expected output:

Response(status=200, bytes=1024)

Classes and state

Track remaining retries behind a small stateful class.

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:

remaining=2

Enums and exhaustive match

Advance a build state machine with exhaustive matching.

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:

RUNNING

Nullable values

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

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:

port=8080

Lookups and modules

Typed maps

Look up a service timeout from a config map.

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

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

Run: vary run main.vary

Expected output:

http=10s

Module-ready helpers

Format an artifact coordinate with a pure helper.

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:

acme:billing:1.4.2

Tests

Shape helpers for assertion

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

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:

5xx,2xx

Run passing assertions

Run two observe assertions against the helper.

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:

Results: 2 passed, 0 failed

Read a failing test

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

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:

Results: 1 passed, 1 failed