---
title: Basic syntax
description: Overview of Agency's TypeScript-derived syntax, covering primitive types, variables, arrays, objects, functions, and other core language constructs.
---

# Basic syntax

Hello and welcome! Agency is a language for building agents, or any other type of system that is complex, hard to debug, and involves non-deterministic outputs. But before you read about that, let's take two minutes to quickly cover installation and syntax.

Agency is a language that compiles down to TypeScript or JavaScript. It borrows its syntax from these languages, if you have used either JS or TS before, a lot of Agency will be familiar to you.

> Note: I'll just say TypeScript everywhere, because writing "TypeScript or JavaScript" gets really boring, but you'll know that I mean both.

You've got primitives: strings, numbers, booleans:

```ts
const name: string = "Alice"
const age: number = 30
const isAgent: boolean = true
```

You can define variables with `let` or `const`. You can add type annotations, just like TypeScript.

You can define arrays and objects:

```ts
const names: string[] = ["Alice", "Bob", "Charlie"]
const person: { name: string, age: number } = { name: "Alice", age: 30 }
```

You can define functions:

```ts
def greet(name: string): string {
  return `Hello, ${name}!`
}
```

You can use if statements, while loops and for loops:

```ts
if (age > 18) {
  print("You are an adult.")
} else {
  print("You are a minor.")
}

while (age < 100) {
  print(`You are ${age} years old.`)
  age = age + 1
}

for (name in names) {
  print(name)
}
```

You can have single-line or multi-line comments.

```ts
// This is a single-line comment
/*
This is a multi-line comment
*/
```

Or doc comments for [documentation generation](/cli/doc):

```ts
/** This is a doc comment for the Person type */
type Person = {
  name: string
  age: number
}
```

You can also write a module-level doc comment using the `@module` tag. This documents the file itself and appears at the top of the generated documentation:

```ts
/** @module
  This module provides utilities for working with dates.
*/
```

> Note: comments must be on their own line, they cannot be at the end of a line containing code.

Regexes are also supported as a primitive:

```ts
// you must use the `re` prefix:
const regex = re/(foo|bar)/

// Use the =~ operator to test if a string matches a regex:
if (name =~ re/^A/) {
  print("Your name starts with A!")
}

// or !~ to test if it doesn't match:
if (str !~ regex) {
  print("The string does not match the regex.")
}
```

Array slice syntax is supported:

```ts
let arr = [1, 2, 3, 4, 5]
const sliced = arr[1:4] // sliced is [2, 3, 4]
const slicedToEnd = arr[2:] // slicedToEnd is [3, 4, 5]
const slicedFromStart = arr[:3] // slicedFromStart is [1, 2, 3]
const negativeSlice = arr[-3:-1] // negativeSlice is [3, 4]
arr[:3] = [10, 20, 30] // arr is now [10, 20, 30, 4, 5]
```

### Unit literals

Agency supports unit literals for time, cost, and size values. They compile to plain numbers at compile time:

```ts
// time
const timeout = 30s       // compiles to 30000 (milliseconds)
const delay = 500ms       // compiles to 500
const duration = 2h       // compiles to 7200000
const week = 1w           // compiles to 604800000

// cost
const budget = $5.00      // compiles to 5.00

// size
const size = 100KB        // compiles to bytes
const mediumSize = 500MB  // compiles to bytes
const bigSize = 2GB       // compiles to bytes


```

Supported time units: `ms` (milliseconds), `s` (seconds), `m` (minutes), `h` (hours), `d` (days), `w` (weeks). All time units normalize to milliseconds.

Supported cost units: `$` (dollars).

Supported size units: `kb` (kilobytes), `mb` (megabytes), `gb` (gigabytes). Case insensitive. All size units normalize to bytes.

Unit math works because both sides normalize to the same base unit:

```ts
1s + 500ms       // 1000 + 500 = 1500
2s * 3           // 2000 * 3 = 6000
if (elapsed > 30s) { ... }
```

Mixing dimensions is a type error:

```ts
1s + $5.00    // ERROR: cannot add time and cost
```

### Reserved names

Identifiers beginning with two underscores (`__name`) are reserved for the compiler and runtime. The codegen uses this prefix for plumbing identifiers like `__ctx`, `__stack`, and `__call`, and the `__internal_` prefix for context-injected stdlib builtins. Do not define functions, variables, or globals whose names start with `__` — your code may compile today but collide with a future internal addition.

### Destructuring and pattern matching

Array and object destructuring work in `let` / `const` declarations and
in `for` loops:

```ts
let [a, b, ...rest]       = items
let { name, age }         = person
for ({ name, age } in users) { ... }
```

The `is` operator, optional guards on `match` arms, and full pattern
matching are documented in the [Pattern matching guide](/guide/pattern-matching).

### JavaScript features that don't exist in Agency
- lambdas
- async/await. Everything is awaited by default, and there are specific constructs for [concurrency](/guide/concurrency).
- classes.