
Vary is a new programming language with its own syntax and semantics. If you've used Python, the code will look familiar (clean, readable, whitespace-friendly) but Vary is not Python. It is its own language with static types, braces, and a built-in mutation testing engine.

Vary compiles to JVM bytecode, so it runs anywhere the JVM runs. It can use Java libraries under the hood, but doesn't expose them directly. It looks nothing like Java, though. There are no annotations, no checked exceptions, no `public static void main`. It ships as a single CLI that handles compiling, running, testing, formatting, and mutation testing.

## What problem does Vary solve?

We wanted a typed language designed to make programming with LLMs better. LLMs generate code that looks right but often isn't, and the usual way to catch that (writing tests, checking coverage) has a gap: tests can pass without actually checking anything. A function can return the wrong value, skip a side effect, or silently drop an error, and the test suite still reports green. Line coverage measures what code ran, not whether the tests would catch a bug.

Vary closes that gap with mutation testing built into the language. `vary mutate` answers the question coverage cannot: if the code changed, would the tests notice? It modifies your code systematically, runs the tests against each change, and reports survivors (mutations the tests miss). Each survivor points to a place where neither you nor your LLM wrote a test that would catch a real bug.

## The language

Vary uses braces, static types with inference, and compile-time null safety.

```vary
def greet(name: Str) -> Str {
    return f"Hello, {name}!"
}

let message: Str? = None
if message is not None {
    print(message)    # narrowed from Str? to Str
}
```

Everything ships as one binary. No test framework, formatter, or build tool to install separately.

```bash
vary run src/main.vary           # compile and run
vary test test/                  # run tests
vary mutate src/ --tests test/   # mutation testing
vary fmt src/                    # format
vary check src/                  # type-check only
```

## Features

| Feature | |
|---------|-------------|
| [Static types](/docs/types/) | `Int`, `Float`, `Bool`, `Str`, nullable `T?` with flow narrowing. Type errors caught at compile time. |
| [Mutation testing](/docs/mutation/lie-detector/) | `vary mutate` modifies code and checks whether tests detect the change. Flags tests that can't actually fail. |
| [Contracts](/docs/contracts/) | `in {}` preconditions and `out (r) {}` postconditions, checked at runtime on every call. |
| [Test DSL](/docs/test-dsl/) | `test "name" { observe expr }` blocks built into the language. |
| [JVM bytecode](/docs/compiler/) | Runs on any system with a JVM. Mutations are applied by bytecode patching, no recompilation. |

## Who is Vary for?

If you've written tests that looked thorough but missed real bugs, mutation testing shows you exactly where. Vary gives you static types and a mutation engine in one toolchain.

## Status

Vary is in alpha. Syntax, APIs, and behaviour may change between releases. It is not ready for production use.

## Next

[Getting started](/docs/getting-started/) covers installation and your first program. The [Language Tour](/docs/tour/basics/) walks through the syntax.
