# Functions

This page is the "Functions" section of the Voxlang language reference. It is generated from LANGUAGE.md in the Voxlang compiler's own repository, so it says what the specification says and nothing more.

A URL is the heading, lowercased, with punctuation dropped and spaces turned into hyphens. Each "##" section of the spec is a page under /docs/, and every heading inside it is a fragment on that page, so "File I/O" is /docs/file-io/ and "Reading a whole file" inside it is /docs/file-io/#reading-a-whole-file.

As data: https://vox-lang.dev/docs/index.json lists every section and every heading with its URL, https://vox-lang.dev/docs/search.json carries one entry per heading with its first sentence and keywords, and https://vox-lang.dev/docs/anchors.json maps every slug to the page it lives on. Search is also a JSON endpoint: https://vox-lang.dev/docs/search?q=<words> returns ranked results as JSON, no page load.

Source: LANGUAGE.md at bf2cba0, 2026-08-22. https://github.com/Vox-lang/vox/blob/bf2cba037976586c30d22a48e7b7246d347f54a1/LANGUAGE.md

[Reference](https://vox-lang.dev/docs/) > Functions

## Definition

```vox fragment
To <function name> with a <type> called <param1> and a <type> called <param2>. Return a <type>, <expression>.
```

No-parameter functions are also valid:

```
To 'show version'.
  Print "1.0.0".

To ping.
  Print "pong".
```

**Examples:**

```
To 'add numbers' with a number called x and a number called y. Return a number, the x add y.

To 'check divisibility' of a number called divisor and a number called dividend. Return a boolean, the divisor modulo the dividend is 0.
```

**Rules:**

- Function name is a bare single word (`add`) or a single-quoted multi-word name (`'add numbers'`)
- Parameters are optional. If present, introduce them with `with` or `of` (both work identically)
- Parameters use `a <type> called <name>` syntax (bare if single-word, `'single-quoted'` if it contains spaces)
- Multiple parameters joined with `and`
- Return type follows `Return a <type>,`

## Function Scope

- Variables declared at top level are global and can be used inside functions — including inside a function written **above** the declaration, because the body runs when it is called, and it reads the global as its declared type either way. A function that runs *before* the declaration has been reached reads the type's empty value — `""`, `[]`, `{}`, an empty buffer, `0`, `0.0`, `false` — never the value the declaration will go on to store. Top-level code has no such licence: see [Declaration Order](https://vox-lang.dev/docs/variables/#declaration-order).
- Variables declared inside a function are local to that function and are not available at top level.
- Referencing an unknown variable inside a function is a compile-time error.
- Assigning to a top-level variable inside a function (`Set g to ...` / `the g is ...`) mutates the global itself, so the new value is visible after the call returns and to every other function.
- Declaring a variable inside a function **shadows** a top-level variable of the same name (`a number called g is 5.` inside a function creates a local `g`); the global is left untouched. Recursion still gets a fresh set of locals per call. This applies to `value` too: its payload and runtime type tag are stored as a pair, in whichever storage (function-local, or the top-level global's own pair of storage locations) that particular `value` uses, so a mutation inside one function is never visible to another unless it is genuinely the same global.

## Parameter and Local Types

Parameters may use any of the 11 expressible types — `number`, `float`, `text`, `boolean`, `list`, `map`, `buffer`, `file`, `time`, `timer`, `value` — and a typed parameter supports the same properties and operations as a top-level variable of that type. The same 11 types are also legal as a declared `Return a <type>,` return type — parameters and returns share one vocabulary, not two. A parameter (or return type) may also be `value`, the dynamic type whose runtime tag travels with its payload across the call (a map rides this as payload + tag 5); see [Dynamic Values (`value`)](https://vox-lang.dev/docs/lists-and-collections/#dynamic-values-value) below.

```
To 'contains token' of a buffer called hay and a text called devname.
  a buffer called needle is " {devname}\n".
  a number called H is hay's size.
  a number called b is byte 1 of hay.
  ...
```

Key points:

- Buffer parameters support `'s size`/`'s empty`/`'s full` and byte access; list parameters support `'s length`/element access; map parameters support `'s length`/`'s empty`/`'s keys`/`'s values` and keyed access, and print as a whole map (`print holder.`, `"{holder}"`); file parameters support file properties.
- A `buffer` parameter **is** the caller's buffer, and stays the caller's buffer across a growth: an `append`, a `resize`, or a byte written past the current capacity moves the block, and the caller's variable follows it there. Declaring a buffer of the same name inside the function names a different buffer from that point on and leaves the caller's alone; `Set <parameter> to ...` is not a rebinding — on a buffer it copies bytes into the buffer the parameter already names, so the caller sees the new bytes.
- Buffers declared **inside** a function body work with every initializer form, including format strings (`is " {devname}\n"`).
- A function call's declared return type is tracked through assignment: reassigning an existing variable from a call (`the label is classify of n.`) preserves the correct type.

### A collection parameter is the caller's collection

A `list` or `map` parameter names the caller's collection, not a copy of it. Whatever the function does to it - setting an element, appending, inserting a key, growing it past whatever size it started at - is what the caller's variable holds when the call returns, however many calls deep the collection was passed:

```
To 'add one to' with a list called items.
    append "x" to items.

a list called xs is ["a"].
'add one to' of xs.
'add one to' of xs.
Print xs's length.    (prints: 3)
```

This is the opposite of a `thing` parameter, which **is** a copy (see [Things](https://vox-lang.dev/docs/things/) below): a thing has no reference to share, and a collection is nothing but one. Only a variable can be written back to - a collection built at the call itself (`'the size of' of [1, 2, 3]`) has nowhere to return growth to, so the function may read and grow it freely but the growth goes nowhere once the call ends.

A `.so` with a `list` or `map` parameter and the programs that `see` it must be built by the same version of Vox.

## Function Calls

In expressions, use the function name followed by `of`, `to`, `with`, or `on` and arguments:

```vox fragment
'add numbers' of 3 and 5
'check divisibility' of the number and 6
calculate with x and y
```

**Rules:**

- Function name is a bare single word (`calculate`) or a single-quoted multi-word name (`'add numbers'`)
- For calls with arguments, use `of`, `to`, `with`, or `on`
- Multiple arguments separated by `and`

Calls with no arguments can be written directly:

```vox fragment
'show version'.
ping.
```

## Calling as Statement

```vox fragment
Print 'add numbers' of x and y.
```

## Reading a result

`Return a <type>,` is optional in the grammar, but it decides where the result may be read. A declared return type travels to every call site, so the result can be printed, interpolated, stored in a list or map slot, or put in a `value` — each of those reads it back as what it is.

A result with **no** declared return type has nothing to be read as, and the compiler will not guess: it is accepted only where the position itself supplies the type, and refused where nothing does.

```vox fragment
To 'opaque label'. Return "hi".

a text called saved is 'opaque label'.   (fine — the declaration says text)
print saved.                             (prints: hi)

print 'opaque label'.                    (compile error: no declared return type)
```

Positions that supply a type: a declared variable's declaration, a later assignment to one, and an argument landing on a declared parameter. Every other position — `print <call>`, a `{...}` interpolation, `append`, a list literal slot, `set element`, a map value, a `value` declaration — needs the return type declared. See [Mixed-Type Lists](https://vox-lang.dev/docs/lists-and-collections/#mixed-type-lists).
