
<!-- path: language/index.md -->
# MoonBit Language

MoonBit is an AI native programming language toolchain for cloud and edge computing. It targets `wasm`, `wasm-gc`, `js`, and `native`, and works well for mixed-backend projects in one module.

**Status**

MoonBit is currently in beta-preview.

MoonBit can already be used in production, with backwards-incompatible changes evaluated seriously and compiler bugs expected to be rare. MoonBit is developed by a full-time team with deep language-toolchain experience, so the ecosystem is moving quickly.

**Main advantages**

- Generate significantly smaller WASM output than any existing solutions.
- Much faster runtime performance.
- State of the art compile-time performance.
- Simple but practical, data-oriented language design.

<!-- path: language/introduction.md -->
## Introduction

A MoonBit program consists of top-level definitions including:

- type definitions
- function definitions
- constant definitions and variable bindings
- `init` functions, `main` function and/or `test` blocks.

### Expressions and Statements

MoonBit distinguishes between statements and expressions. In a function body, only the last clause should be an expression, which serves as a return value. For example:

```moonbit
fn foo() -> Int {
  let x = 1
  x + 1
}

fn bar() -> Int {
  let x = 1
  //! x + 1
  x + 2
}
```

Expressions include:

- Value literals (e.g. Boolean values, numbers, characters, strings, arrays, tuples, structs)
- Arithmetical, logical, or comparison operations
- Accesses to array elements (e.g. `a[0]`), struct fields (e.g `r.x`), tuple components (e.g. `t.0`), etc.
- Variables and (capitalized) enum constructors
- Anonymous local function definitions
- `match`, `if`, `loop` expressions, etc.

Statements include:

- Named local function definitions
- Local variable bindings
- Assignments
- `return` statements
- Any expression whose return type is `Unit`, (e.g. `ignore`)

A code block can contain multiple statements and one expression, and the value of the expression is the value of the code block.

### Variable Binding

A variable can be declared as mutable or immutable using `let mut` or `let`, respectively. A mutable variable can be reassigned to a new value, while an immutable one cannot.

A constant can only be declared at top level and cannot be changed.

```moonbit
let zero = 0

const ZERO = 0

fn main {
  //! const ZERO = 0 
  let mut i = 10
  i = 20
  println(i + zero + ZERO)
}
```

##### NOTE
A top level variable binding

- requires **explicit** type annotation (unless defined using literals such as string, byte or numbers)
- can't be mutable (use `Ref` instead)

### Naming conventions

Variables, functions should start with lowercase letters `a-z` and can contain letters, numbers, underscore, and other non-ascii unicode chars.
It is recommended to name them with snake_case.

Constants, types should start with uppercase letters `A-Z` and can contain letters, numbers, underscore, and other non-ascii unicode chars.
It is recommended to name them with PascalCase or SCREAMING_SNAKE_CASE.

#### Keywords

The following are the keywords and should not be used:

```json
[
  "as", "else", "extern", "fn", "fnalias", "if", "let", "const", "match", "using",
  "mut", "type", "typealias", "struct", "enum", "extenum", "trait",
  "traitalias", "derive", "while", "break", "continue", "import", "return",
  "throw", "raise", "try", "catch", "pub", "priv", "proof_assert", "proof_let",
  "readonly", "true", "false", "_", "test", "loop", "for", "in", "impl", "with",
  "guard", "async", "is", "suberror", "and", "letrec", "enumview", "noraise",
  "defer", "lexmatch", "where", "declare", "nobreak",
]
```

#### Reserved Keywords

The following are the reserved keywords. Using them would introduce a warning.
They might be turned into keywords in the future.

```json
[
  "module", "move", "ref", "static", "super", "unsafe", "use", "await",
  "dyn", "abstract", "do", "final", "macro", "override", "typeof", "virtual", "yield",
  "local", "method", "alias", "assert", "package", "recur", "using", "enumview",
  "isnot", "define", "downcast", "inherit", "member", "namespace", "static", "upcast",
  "use", "void", "lazy", "include", "mixin", "protected", "sealed", "constructor",
  "atomic", "volatile", "anyframe", "anytype", "asm", "await", "comptime", "errdefer",
  "export", "opaque", "orelse", "resume", "threadlocal", "unreachable", "dynclass",
  "dynobj", "dynrec", "var", "finally", "noasync", "assume",
]
```

### Program entrance

#### `init` and `main`

There is a specialized function called `init` function. The `init` function is special:

1. It has no parameter list nor return type.
2. There can be multiple `init` functions in the same package.
3. An `init` function can't be explicitly called or referred to by other functions.
   Instead, all `init` functions will be implicitly called when initializing a package. Therefore, `init` functions should only consist of statements.

```moonbit
fn init {
  let x = 1
  println(x)
}
```

There is another specialized function called `main` function. The `main` function is the main entrance of the program, and it will be executed after the initialization stage.

Same as the `init` function, it has no parameter list nor return type.

```moonbit
fn main {
  let x = 2
  println(x)
}
```

The previous two code snippets will print the following at runtime:

```bash
1
2
```

Only packages that are `main` packages can define such `main` function. Check out [build system tutorial](../toolchain/moon/tutorial.md) for detail. In current projects, this is configured in `moon.pkg`:

```text
options(
  "is-main": true,
)
```

#### `test`

There's also a top-level structure called `test` block. A `test` block defines inline tests, such as:

```moonbit
test "test_name" {
  assert_eq(1 + 1, 2)
  assert_eq(2 + 2, 4)
  debug_inspect([1, 2, 3], content="[1, 2, 3]")
}
```

The following contents will use `test` block and `main` function to demonstrate the execution result,
and we assume that all the `test` blocks pass unless stated otherwise.

<!-- path: language/fundamentals.md -->
## Fundamentals

### Built-in Data Structures

#### Unit

`Unit` is a built-in type in MoonBit that represents the absence of a meaningful value. It has only one value, written as `()`. `Unit` is similar to `void` in languages like C/C++/Java, but unlike `void`, it is a real type and can be used anywhere a type is expected.

The `Unit` type is commonly used as the return type for functions that perform some action but do not produce a meaningful result:

```moonbit
fn print_hello() -> Unit {
  println("Hello, world!")
}
```

Unlike some other languages, MoonBit treats `Unit` as a first-class type, allowing it to be used in generics, stored in data structures, and passed as function arguments.

#### Boolean

MoonBit has a built-in boolean type, which has two values: `true` and `false`. The boolean type is used in conditional expressions and control structures. Use `!` to negate a boolean value; `not(x)` is equivalent.

```moonbit
let a = true
let b = false
let c = a && b
let d = a || b
let e = !a
let f = !(a && b)
```

#### Number

MoonBit have integer type and floating point type:

| type     | description                                       | example                    |
|----------|---------------------------------------------------|----------------------------|
| `Int16`  | 16-bit signed integer                             | `(42 : Int16)`             |
| `Int`    | 32-bit signed integer                             | `42`                       |
| `Int64`  | 64-bit signed integer                             | `1000L`                    |
| `UInt16` | 16-bit unsigned integer                           | `(14 : UInt16)`            |
| `UInt`   | 32-bit unsigned integer                           | `14U`                      |
| `UInt64` | 64-bit unsigned integer                           | `14UL`                     |
| `Double` | 64-bit floating point, defined by IEEE754         | `3.14`                     |
| `Float`  | 32-bit floating point                             | `(3.14 : Float)`           |
| `BigInt` | represents numeric values larger than other types | `10000000000000000000000N` |

MoonBit also supports numeric literals, including decimal, binary, octal, and hexadecimal numbers.

To improve readability, you may place underscores in the middle of numeric literals such as `1_000_000`. Note that underscores can be placed anywhere within a number, not just every three digits.

- Decimal numbers can have underscore between the numbers.

  By default, an int literal is signed 32-bit number. For unsigned numbers, a postfix `U` is needed; for 64-bit numbers, a postfix `L` is needed.
  ```moonbit
  let a = 1234
  let b : Int = 1_000_000 + a
  let unsigned_num       : UInt   = 4_294_967_295U
  let large_num          : Int64  = 9_223_372_036_854_775_807L
  let unsigned_large_num : UInt64 = 18_446_744_073_709_551_615UL
  ```
- A binary number has a leading zero followed by a letter "B", i.e. `0b`/`0B`.
  Note that the digits after `0b`/`0B` must be `0` or `1`.
  ```moonbit
  let bin = 0b110010
  let another_bin = 0B110010
  ```
- An octal number has a leading zero followed by a letter "O", i.e. `0o`/`0O`.
  Note that the digits after `0o`/`0O` must be in the range from `0` through `7`:
  ```moonbit
  let octal = 0o1234
  let another_octal = 0O1234
  ```
- A hexadecimal number has a leading zero followed by a letter "X", i.e. `0x`/`0X`.
  Note that the digits after the `0x`/`0X` must be in the range `0123456789ABCDEF`.
  ```moonbit
  let hex = 0XA
  let another_hex = 0xA_B_C
  ```
- A floating-point number literal is 64-bit floating-point number. To define a float, type annotation is needed.
  ```moonbit
  let double = 3.14 // Double
  let float : Float = 3.14
  let float2 = (3.14 : Float)
  ```

  A 64-bit floating-point number can also be defined using hexadecimal format:
  ```moonbit
  let hex_double = 0x1.2P3 // (1.0 + 2 / 16) * 2^(+3) == 9
  ```

When the expected type is known, MoonBit can automatically overload literal, and there is no need to specify the type of number via letter postfix:

```moonbit
let int : Int = 42
let uint : UInt = 42
let int64 : Int64 = 42
let double : Double = 42
let float : Float = 42
let bigint : BigInt = 42
```

##### SEE ALSO
[Overloaded Literals]()

#### String

`String` holds a sequence of UTF-16 code units. You can use double quotes to create a string, or use `#|` to write a multi-line string.

```moonbit
let a = "兔rabbit"
debug_inspect(a.code_unit_at(0).to_char(), content="Some('兔')")
debug_inspect(a.code_unit_at(1).to_char(), content="Some('r')")
let b =
  #| Hello
  #| MoonBit\n
  #|
println(b)
```

```default
 Hello
 MoonBit\n

```

In double quotes string, a backslash followed by certain special characters forms an escape sequence:

| escape sequences       | description                                          |
|------------------------|------------------------------------------------------|
| `\n`, `\r`, `\t`, `\b` | New line, Carriage return, Horizontal tab, Backspace |
| `\\`                   | Backslash                                            |
| `\u5154` , `\u{1F600}` | Unicode escape sequence                              |

MoonBit supports string interpolation. It enables you to substitute variables within interpolated strings. This feature simplifies the process of constructing dynamic strings by directly embedding variable values into the text. Variables used for string interpolation must implement the [`Show` trait](methods.md#builtin-traits).

```moonbit
let x = 42
println("The answer is \{x}")
```

##### NOTE
The interpolated expression can not contain newline, `{}` or `"`.

Multi-line strings can be defined using the leading `#|` or `$|`, where the former will keep the raw string and the latter will perform the escape and interpolation:

```moonbit
let lang = "MoonBit"
let raw =
  #| Hello
  #| ---
  #| \{lang}
  #| ---
let interp =
  $| Hello
  $| ---
  $| \{lang}
  $| ---
println(raw)
println(interp)
```

```default
 Hello
 ---
 \{lang}
 ---
 Hello
 ---
 MoonBit
 ---
```

Avoid mixing `$|` and `#|` within the same multi-line string; pick one style for the whole block.

The [VSCode extension](../toolchain/vscode/index.md#actions) includes an action that can turn pasted documents into a plain multi-line string and switch between plain text and MoonBit multi-line strings.

When the expected type is `String` , the array literal syntax is overloaded to
construct the `String` by specifying each character in the string.

```moonbit
test {
  let c : Char = '中'
  let s : String = [c, '文']
  inspect(s, content="中文")
}
```

##### SEE ALSO
API: [https://mooncakes.io/docs/moonbitlang/core/string](https://mooncakes.io/docs/moonbitlang/core/string)

[Overloaded Literals]()

#### Char

`Char` represents a Unicode code point.

```moonbit
let a : Char = 'A'
let b = '兔'
let zero = '\u{30}'
let zero = '\u0030'
```

Char literals can be overloaded to type `Int` or `UInt16` when it is the expected type:

```moonbit
test {
  let s : String = "hello"
  let b : UInt16 = s.code_unit_at(0) // 'h'
  assert_eq(b, 'h') // 'h' is overloaded to UInt16
  let c : Int = '兔'
  // Not ok : exceed range
  // let d : UInt16 = '𠮷'
}
```

##### SEE ALSO
API: [https://mooncakes.io/docs/moonbitlang/core/char](https://mooncakes.io/docs/moonbitlang/core/char)

[Overloaded Literals]()

#### Byte(s)

A byte literal in MoonBit is either a single ASCII character or a single escape, have the form of `b'...'`. Byte literals are of type `Byte`. For example:

```moonbit
fn main {
  let b1 : Byte = b'a'
  println(b1.to_int())
  let b2 = b'\xff'
  println(b2.to_int())
}
```

```default
97
255
```

A `Bytes` is an immutable sequence of bytes. Similar to byte, bytes literals have the form of `b"..."`. For example:

```moonbit
test {
  let b1 : Bytes = b"abcd"
  let b2 = b"\x61\x62\x63\x64"
  assert_eq(b1, b2)
}
```

The byte literal and bytes literal also support escape sequences, but different from those in string literals. The following table lists the supported escape sequences for byte and bytes literals:

| escape sequences       | description                                          |
|------------------------|------------------------------------------------------|
| `\n`, `\r`, `\t`, `\b` | New line, Carriage return, Horizontal tab, Backspace |
| `\\`                   | Backslash                                            |
| `\x41`                 | Hexadecimal escape sequence                          |
| `\o102`                | Octal escape sequence                                |

##### NOTE
You can use `@buffer.T` to construct bytes by writing various types of data. For example:

```moonbit
test "buffer 1" {
  let buf : @buffer.Buffer = Buffer()
  buf.write_bytes(b"Hello")
  buf.write_byte(b'!')
  assert_eq(buf.contents(), b"Hello!")
}
```

Array literals can also be overloaded to construct a `Bytes` sequence by
specifying each byte in the sequence.

```moonbit
test {
  let b : Byte = b'\xFF'
  let bs : Bytes = [b, b'\x01']
  inspect(
    bs,
    content=(
      #|b"\xff\x01"
    ),
  )
}
```

##### SEE ALSO
API for `Byte`: [https://mooncakes.io/docs/moonbitlang/core/byte](https://mooncakes.io/docs/moonbitlang/core/byte)<br />
\\\\
API for `Bytes`: [https://mooncakes.io/docs/moonbitlang/core/bytes](https://mooncakes.io/docs/moonbitlang/core/bytes)<br />
\\\\
API for `@buffer.T`: [https://mooncakes.io/docs/moonbitlang/core/buffer](https://mooncakes.io/docs/moonbitlang/core/buffer)

[Overloaded Literals]()

##### Choosing a Byte Container

MoonBit has several byte-oriented container types. They are related, but they
serve different jobs:

| Type                 | Ownership / mutability   | Resizable   | Typical use                                                   |
|----------------------|--------------------------|-------------|---------------------------------------------------------------|
| `Bytes`              | owned, immutable         | no          | final byte payloads, API boundaries, serialized data          |
| `BytesView`          | borrowed, immutable view | no          | slicing or parsing existing bytes without copying             |
| `Array[Byte]`        | owned, mutable           | yes         | general-purpose mutable byte storage                          |
| `FixedArray[Byte]`   | owned, mutable           | no          | fixed-size working buffers                                    |
| `ArrayView[Byte]`    | borrowed array view      | no          | passing slices of array-backed byte storage without ownership |
| `MutArrayView[Byte]` | borrowed, mutable view   | no          | mutating borrowed array-backed byte storage in place          |
| `@buffer.Buffer`     | owned, mutable builder   | yes         | incrementally constructing bytes, then calling `contents()`   |

Two common distinctions matter:

- `Bytes` versus `BytesView`: owned immutable data versus a borrowed immutable slice.
- `Array[Byte]` versus `ArrayView[Byte]` / `MutArrayView[Byte]`: owned mutable storage versus borrowed readonly or mutable views over it.

`ReadOnlyArray[Byte]` and `MutArrayView[Byte]` are the corresponding read-only
and mutable view types when you need to express those constraints explicitly.
Pattern matching and bitstring parsing also work on these byte containers; see
[Array Pattern]() and [Bitstring Pattern]().

#### Tuple

A tuple is a collection of finite values constructed using round brackets `()` with the elements separated by commas `,`. The order of elements matters; for example, `(1,true)` and `(true,1)` have different types. Here's an example:

```moonbit
fn main {
  fn pack(
    a : Bool,
    b : Int,
    c : String,
    d : Double
  ) -> (Bool, Int, String, Double) {
    (a, b, c, d)
  }

  let quad = pack(false, 100, "text", 3.14)
  let (bool_val, int_val, str, float_val) = quad
  println("\{bool_val} \{int_val} \{str} \{float_val}")
}
```

```default
false 100 text 3.14
```

Tuples can be accessed via pattern matching or index:

```moonbit
test {
  let t = (1, 2)
  let (x1, y1) = t
  let x2 = t.0
  let y2 = t.1
  assert_eq(x1, x2)
  assert_eq(y1, y2)
}
```

#### Ref

A `Ref[T]` is a mutable reference containing a value `val` of type `T`.

It can be constructed using `{ val : x }`, and can be accessed using `ref.val`. See [struct]() for detailed explanation.

```moonbit
let a : Ref[Int] = { val: 100 }

test {
  a.val = 200
  assert_eq(a.val, 200)
  a.val += 1
  assert_eq(a.val, 201)
}
```

##### SEE ALSO
API: [https://mooncakes.io/docs/moonbitlang/core/ref](https://mooncakes.io/docs/moonbitlang/core/ref)

#### Option and Result

`Option` and `Result` are the most common types to represent a possible error or failure in MoonBit.

- `Option[T]` represents a possibly missing value of type `T`. It can be abbreviated as `T?`.
- `Result[T, E]` represents either a value of type `T` or an error of type `E`.

See [enum]() for detailed explanation.

```moonbit
test {
  let a : Int? = None
  let b : Option[Int] = Some(42)
  let c : Result[Int, String] = Ok(42)
  let d : Result[Int, String] = Err("error")
  match a {
    Some(_) => assert_true(false)
    None => assert_true(true)
  }
  match d {
    Ok(_) => assert_true(false)
    Err(_) => assert_true(true)
  }
}
```

##### SEE ALSO
API for `Option`: [https://mooncakes.io/docs/moonbitlang/core/option](https://mooncakes.io/docs/moonbitlang/core/option)<br />
\\\\
API for `Result`: [https://mooncakes.io/docs/moonbitlang/core/result](https://mooncakes.io/docs/moonbitlang/core/result)

#### Array

An array is a finite sequence of values constructed using square brackets `[]`, with elements separated by commas `,`. For example:

```moonbit
let numbers = [1, 2, 3, 4]
```

You can use `numbers[x]` to refer to the xth element. The index starts from zero.

```moonbit
test {
  let numbers = [1, 2, 3, 4]
  let a = numbers[2]
  numbers[3] = 5
  let b = a + numbers[3]
  assert_eq(b, 8)
}
```

There are `Array[T]` and `FixedArray[T]`. Views are provided by `ArrayView[T]`
and `MutArrayView[T]` (see below).

`Array[T]` can grow in size, while `FixedArray[T]` has a fixed size, thus it needs to be created with initial value.

##### WARNING
A common pitfall is creating `FixedArray` with the same initial value:

```moonbit
test {
  let two_dimension_array = FixedArray::make(10, FixedArray::make(10, 0))
  two_dimension_array[0][5] = 10
  assert_eq(two_dimension_array[5][5], 10)
}
```

This is because all the cells reference to the same object (the `FixedArray[Int]` in this case). One should use `FixedArray::makei()` instead which creates an object for each index.

```moonbit
test {
  let two_dimension_array = FixedArray::makei(10, fn(_i) {
    FixedArray::make(10, 0)
  })
  two_dimension_array[0][5] = 10
  assert_eq(two_dimension_array[5][5], 0)
}
```

When the expected type is known, MoonBit can automatically overload array, otherwise
`Array[T]` is created:

```moonbit
let fixed_array_1 : FixedArray[Int] = [1, 2, 3]

let fixed_array_2 = ([1, 2, 3] : FixedArray[Int])

let array_3 : Array[Int] = [1, 2, 3] // Array[Int]
```

##### SEE ALSO
API: [https://mooncakes.io/docs/moonbitlang/core/array](https://mooncakes.io/docs/moonbitlang/core/array)

[Overloaded Literals]()

##### ArrayView

Analogous to `slice` in other languages, the view is a reference to a
specific segment of collections. You can use `data[start:end]` to create a
view of array `data`, referencing elements from `start` to `end` (exclusive).
Both `start` and `end` indices can be omitted.

##### NOTE
`ArrayView` is an immutable data structure on its own, but the underlying
`Array` or `FixedArray` could be modified. For a mutable view, use
`MutArrayView[T]` via `data.mut_view(...)`.

```moonbit
test {
  let xs = [0, 1, 2, 3, 4, 5]
  let s1 : ArrayView[Int] = xs[2:]
  @test.assert_eq(s1.to_owned(), [2, 3, 4, 5])
  @test.assert_eq(xs[:4].to_owned(), [0, 1, 2, 3])
  @test.assert_eq(xs[2:5].to_owned(), [2, 3, 4])
  @test.assert_eq(xs[:].to_owned(), [0, 1, 2, 3, 4, 5])
  let mv : MutArrayView[Int] = xs.mut_view(start=1, end=3)
  mv[0] = 99
  inspect(xs[1], content="99")
}
```

##### SEE ALSO
API: [https://mooncakes.io/docs/moonbitlang/core/array](https://mooncakes.io/docs/moonbitlang/core/array)

#### Map

MoonBit provides a hash map data structure that preserves insertion order called `Map` in its standard library.
`Map`s can be created via a convenient literal syntax:

```moonbit
let map : Map[String, Int] = { "x": 1, "y": 2, "z": 3 }
```

Currently keys in map literal syntax must be constant. `Map`s can also be destructed elegantly with pattern matching, see [Map Pattern]().

##### SEE ALSO
API: [https://mooncakes.io/docs/moonbitlang/core/builtin#Map](https://mooncakes.io/docs/moonbitlang/core/builtin#Map)

[Overloaded Literals]()

#### Json

MoonBit supports convenient json handling by overloading literals.
When the expected type of an expression is `Json`, number, string, array and map literals can be directly used to create json data:

```moonbit
let moon_pkg_json_example : Json = {
  "import": ["moonbitlang/core/builtin", "moonbitlang/core/coverage"],
  "test-import": ["moonbitlang/core/random"],
}
```

Json values can be pattern matched too, see [Json Pattern]().

##### SEE ALSO
API: [https://mooncakes.io/docs/moonbitlang/core/json](https://mooncakes.io/docs/moonbitlang/core/json)

[Overloaded Literals]()

### Overloaded Literals

Overloaded literals allow you to use the same syntax to represent different types of values.
For example, you can use `1` to represent `UInt` or `Double` depending on the expected type. If the expected type is not known, the literal will be interpreted as `Int` by default.

```moonbit
fn expect_double(x : Double) -> Unit {

}

test {
  let x = 1 // type of x is Int
  let y : Double = 1
  expect_double(1)
}
```

The overloaded literals can be composed. If array literal can be overloaded to `Bytes` , and number literal can be overloaded to `Byte` , then you can overload `[1,2,3]` to `Bytes` as well. Here is a table of overloaded literals in MoonBit:

| Overloaded literal                                          | Default type   | Can be overloaded to                                                              |
|-------------------------------------------------------------|----------------|-----------------------------------------------------------------------------------|
| `10`, `0xFF`, `0o377`, `10_000`                             | `Int`          | `UInt`, `Int64`, `UInt64`, `Int16`, `UInt16`, `Byte`, `Double`, `Float`, `BigInt` |
| `"str"`                                                     | `String`       | —                                                                                 |
| `'c'`                                                       | `Char`         | `Int`                                                                             |
| `3.14`                                                      | `Double`       | `Float`                                                                           |
| `[a, b, c]` (where the types of literals a, b, and c are E) | `Array[E]`     | `FixedArray[E]`, `String`  (if E is of type Char), `Bytes` (if E is of type Byte) |

There are also some similar overloading rules in pattern. For more details, see [Pattern Matching]().

##### NOTE
Literal overloading is not the same as value conversion. To convert a variable to a different type, you can use methods prefixed with `to_`, such as `to_int()`, `to_double()`, etc.

#### Escape Sequences in Overloaded Literals

Escape sequences can be used in overloaded `"..."` literals and `'...'` literals. The interpretation of escape sequences depends on the types they are overloaded to:

- Simple escape sequences

  Including `\n`, `\r`, `\t`, `\\`, and `\b`. These escape sequences are supported in any `"..."` or `'...'` literals. They are interpreted as their respective `Char` or `Byte` in `String` or `Bytes`.
- Byte escape sequences

  The `\x41` and `\o102` escape sequences represent a Byte. These are supported in literals overloaded to `Bytes` and `Byte`.
- Unicode escape sequences

  The `\u5154` and `\u{1F600}` escape sequences represent a `Char`. These are supported in literals of type `String` and `Char`.

### Functions

Functions take arguments and produce a result. In MoonBit, functions are first-class, which means that functions can be arguments or return values of other functions. MoonBit's naming convention requires that function names should not begin with uppercase letters (A-Z). Compare for constructors in the `enum` section below.

#### Top-Level Functions

Functions can be defined as top-level or local. We can use the `fn` keyword to define a top-level function that sums three integers and returns the result, as follows:

```moonbit
fn add3(x : Int, y : Int, z : Int) -> Int {
  x + y + z
}
```

Note that the arguments and return value of top-level functions require **explicit** type annotations.

Top-level functions and methods can also be introduced with `declare`.
A declared function has a signature but no body, and a later implementation must match that signature.
This is useful when you want to make an API shape available before placing its implementation.

```moonbit
declare fn declared_add(x : Int, y : Int) -> Int

fn declared_add(x : Int, y : Int) -> Int {
  x + y
}

struct DeclaredCounter(Int)

declare fn DeclaredCounter::value(self : Self) -> Int

fn DeclaredCounter::value(self : Self) -> Int {
  self.0
}

test "declared functions" {
  @test.assert_eq(declared_add(1, 2), 3)
  @test.assert_eq(DeclaredCounter(4).value(), 4)
}
```

If a declared function has an implementation, the declaration and the implementation must agree on the function name, visibility, type parameters, parameters, return type, and effects.

#### Local Functions

Local functions can be named or anonymous. Type annotations can be omitted for local function definitions: they can be automatically inferred in most cases. For example:

```moonbit
fn local_1() -> Int {
  fn inc(x) { // named as `inc`
    x + 1
  }
  // anonymous, instantly applied to integer literal 6
  (fn(x) { x + inc(2) })(6)
}

test {
  assert_eq(local_1(), 9)
}
```

For simple anonymous function, MoonBit provides a very concise syntax called arrow function:

```moonbit
  [1, 2, 3].eachi((i, x) => println("\{i} => \{x}"))
  // parenthesis can be omitted when there is only one parameter
  [1, 2, 3].each(x => println(x * x))
```

Although local function supports type inference for types of parameters and return value,
*effect inference* is only supported for the arrow function syntax.
If a `fn` may [raise error](error-handling.md)
or [perform asynchronous operations](async-experimental.md),
it must be explicitly annotated with `raise` or `async`.

Functions, whether named or anonymous, are *lexical closures*: any identifiers without a local binding must refer to bindings from a surrounding lexical scope. For example:

```moonbit
let global_y = 3

fn local_2(x : Int) -> (Int, Int) {
  fn inc() {
    x + 1
  }

  fn four() {
    global_y + 1
  }

  (inc(), four())
}

test {
  @test.assert_eq(local_2(3), (4, 4))
}
```

A local function can only refer to itself and other previously defined local functions.
To define  mutually recursive local functions, use the syntax `letrec f = .. and g = ..` instead:

```moonbit
  fn f(x) {
    // `f` can refer to itself here, but cannot use `g`
    if x > 0 {
      f(x - 1)
    }
  }

  fn g(x) {
    // `g` can refer to `f` and `g` itself
    if x < 0 {
      f(-x)
    } else {
      f(x)
    }
  }
  // mutually recursive local functions
  letrec even = x => x == 0 || odd(x - 1)
  and odd = x => x != 0 && even(x - 1)
```

#### Function Applications

A function can be applied to a list of arguments in parentheses:

```moonbit
add3(1, 2, 7)
```

This works whether `add3` is a function defined with a name (as in the previous example), or a variable bound to a function value, as shown below:

```moonbit
test {
  let add3 = fn(x, y, z) { x + y + z }
  assert_eq(add3(1, 2, 7), 10)
}
```

The expression `add3(1, 2, 7)` returns `10`. Any expression that evaluates to a function value is applicable:

```moonbit
test {
  let f = fn(x) { x + 1 }
  let g = fn(x) { x + 2 }
  let w = (if true { f } else { g })(3)
  assert_eq(w, 4)
}
```

#### Partial Applications

Partial application is a technique of applying a function to some of its arguments, resulting in a new function that takes the remaining arguments. In MoonBit, partial application is achieved by using the `_` operator in function application:

```moonbit
fn add(x : Int, y : Int) -> Int {
  x + y
}

test {
  let add10 : (Int) -> Int = x => add(10, x)
  println(add10(5)) // prints 15
  println(add10(10)) // prints 20
}
```

The `_` operator represents the missing argument in parentheses. The partial application allows multiple `_` in the same parentheses.
For example, `Array::fold(_, _, init=5)` is equivalent to `fn(x, y) { Array::fold(x, y, init=5) }`.

The `_` operator can also be used in enum creation, dot style function calls and in the pipelines.

#### Labelled arguments

**Top-level** functions can declare labelled argument with the syntax `label~ : Type`. `label` will also serve as parameter name inside function body:

```moonbit
fn labelled_1(arg1~ : Int, arg2~ : Int) -> Int {
  arg1 + arg2
}
```

Labelled arguments can be supplied via the syntax `label=arg`. `label=label` can be abbreviated as `label~`:

```moonbit
test {
  let arg1 = 1
  assert_eq(labelled_1(arg2=2, arg1~), 3)
}
```

Labelled function can be supplied in any order. The evaluation order of arguments is the same as the order of parameters in function declaration.

#### Optional arguments

An argument can be made optional by supplying a default expression with the syntax `label?: Type = default_expr`, where the `default_expr` may be omitted. If this argument is not supplied at call site, the default expression will be used:

```moonbit
fn optional(opt? : Int = 42) -> Int {
  opt
}

test {
  assert_eq(optional(), 42)
  assert_eq(optional(opt=0), 0)
}
```

The default expression will be evaluated every time it is used. And the side effect in the default expression, if any, will also be triggered. For example:

```moonbit
fn incr(counter? : Ref[Int] = { val: 0 }) -> Ref[Int] {
  counter.val = counter.val + 1
  counter
}

test {
  @test.assert_eq(incr().val, 1)
  @test.assert_eq(incr().val, 1)
  let counter : Ref[Int] = { val: 0 }
  @test.assert_eq(incr(counter~).val, 1)
  @test.assert_eq(incr(counter~).val, 2)
}
```

Optional argument values are regular expressions at the call site. You can pass
expressions that may raise errors or call async functions when in a `raise` or
`async` context:

```moonbit
fn may_fail(x : Int) -> Int raise Failure {
  if x < 0 {
    fail("negative")
  }
  x
}

fn add_with_optional(base : Int, extra? : Int = 1) -> Int {
  base + extra
}

test {
  inspect(add_with_optional(1, extra=may_fail(2)), content="3")
}
```

For async functions, optional argument expressions can call async functions as
usual:

```moonbit

///|
async fn fetch_default() -> Int {
  ...
}

///|
async fn build(x? : Int = fetch_default()) -> Int {
  ...
}

///|
async fn use_value() -> Int {
  build(x=fetch_default())
}
```

If you want to share the result of default expression between different function calls, you can lift the default expression to a toplevel `let` declaration:

```moonbit
let default_counter : Ref[Int] = { val: 0 }

fn incr_2(counter? : Ref[Int] = default_counter) -> Int {
  counter.val = counter.val + 1
  counter.val
}

test {
  assert_eq(incr_2(), 1)
  assert_eq(incr_2(), 2)
}
```

The default expression can depend on previous arguments, such as:

```moonbit
fn create_rectangle(a : Int, b? : Int = a) -> (Int, Int) {
  (a, b)
}

test {
  debug_inspect(create_rectangle(10), content="(10, 10)")
}
```

##### Optional arguments without default values

It is quite common to have different semantics when a user does not provide a value.
Optional arguments without default values have type `T?` and `None` as the default value.
When supplying this kind of optional argument directly, MoonBit will automatically wrap the value with `Some`:

```moonbit
fn new_image(width? : Int, height? : Int) -> Image {
  if width is Some(w) {
    ...
  }
  ...
}

let img2 : Image = new_image(width=1920, height=1080)
```

Sometimes, it is also useful to pass a value of type `T?` directly,
for example when forwarding optional argument.
MoonBit provides a syntax `label?=value` for this, with `label?` being an abbreviation of `label?=label`:

```moonbit
fn image(width? : Int, height? : Int) -> Image {
  ...
}

fn fixed_width_image(height? : Int) -> Image {
  image(width=1920, height?)
}
```

<a id="autofill-arguments"></a>

#### Autofill arguments

MoonBit supports filling specific types of arguments automatically at different call site, such as the source location of a function call.
To declare an autofill argument, simply declare a labelled argument, and add a function attribute `#callsite(autofill(param_a, param_b))`.
Now if the argument is not explicitly supplied, MoonBit will automatically fill it at the call site.

Currently MoonBit supports two types of autofill arguments, `SourceLoc`, which is the source location of the whole function call,
and `ArgsLoc`, which is an array containing the source location of each argument, if any:

```moonbit
##callsite(autofill(loc, args_loc))
fn f(_x : Int, loc~ : SourceLoc, args_loc~ : ArgsLoc) -> String {
  (
    $|loc of whole function call: \{loc}
    $|loc of arguments: \{args_loc}
  )
  // loc of whole function call: <filename>:7:3-7:10
  // loc of arguments: [Some(<filename>:7:5-7:6), Some(<filename>:7:8-7:9), None, None]
}
```

Autofill arguments are very useful for writing debugging and testing utilities.

#### Function alias

MoonBit allows calling functions with alternative names via function alias. Function alias can be declared as follows:

```moonbit
##alias(g)
##alias(h, visibility="pub")
fn k() -> Bool {
  true
}
```

You can also create function alias that has different visibility with the field `visibility`.

### Control Structures

#### Conditional Expressions

A conditional expression consists of a condition, a consequent, and an optional `else` clause or `else if` clause.

```moonbit
if x == y {
  expr1
} else if x == z {
  expr2
} else {
  expr3
}
```

The curly brackets around the consequent are required.

Note that a conditional expression always returns a value in MoonBit, and the return values of the consequent and the else clause must be of the same type. Here is an example:

```moonbit
let initial = if size < 1 { 1 } else { size }
```

The `else` clause can only be omitted if the return value has type `Unit`.

#### Match Expression

The `match` expression is similar to conditional expression, but it uses [pattern matching]() to decide which consequent to evaluate and extracting variables at the same time.

```moonbit
fn decide_sport(weather : String, humidity : Int) -> String {
  match weather {
    "sunny" => "tennis"
    "rainy" => if humidity > 80 { "swimming" } else { "football" }
    _ => "unknown"
  }
}

test {
  assert_eq(decide_sport("sunny", 0), "tennis")
}
```

If a possible condition is omitted, the compiler will issue a warning, and the program will terminate if that case were reached.

#### Guard Statement

The `guard` statement is used to check a specified invariant.
If the condition of the invariant is satisfied, the program continues executing
the subsequent statements and returns. If the condition is not satisfied (i.e., false),
the code in the `else` block is executed and its evaluation result is returned (the subsequent statements are skipped).

```moonbit
fn guarded_get(array : Array[Int], index : Int) -> Int? {
  guard index >= 0 && index < array.length() else { None }
  Some(array[index])
}

test {
  debug_inspect(guarded_get([1, 2, 3], -1), content="None")
}
```

##### Guard statement and is expression

The `let` statement can be used with [pattern matching](). However, `let` statement can only handle one case. And using [is expression]() with `guard` statement can solve this issue.

In the following example, `getProcessedText` assumes that the input `path` points to resources that are all plain text,
and it uses the `guard` statement to ensure this invariant while extracting the plain text resource.
Compared to using a `match` statement, the subsequent processing of `text` can have one less level of indentation.

```moonbit
enum Resource {
  Folder(Array[String])
  PlainText(String)
  JsonConfig(Json)
}

fn getProcessedText(
  resources : Map[String, Resource],
  path : String,
) -> String raise Error {
  guard resources.get(path) is Some(resource) else { fail("\{path} not found") }
  guard resource is PlainText(text) else { fail("\{path} is not plain text") }
  process(text)
}
```

When the `else` part is omitted, the program terminates if the condition specified
in the `guard` statement is not true or cannot be matched.

```moonbit
guard condition  // <=> guard condition else { panic() }
guard expr is Some(x)
// <=> guard expr is Some(x) else { _ => panic() }
```

#### While loop

In MoonBit, `while` loop can be used to execute a block of code repeatedly as long as a condition is true. The condition is evaluated before executing the block of code. The `while` loop is defined using the `while` keyword, followed by a condition and the loop body. The loop body is a sequence of statements. The loop body is executed as long as the condition is true.

```moonbit
fn main {
  let mut i = 5
  while i > 0 {
    println(i)
    i = i - 1
  }
}
```

```default
5
4
3
2
1
```

The loop body supports `break` and `continue`. Using `break` allows you to exit the current loop, while using `continue` skips the remaining part of the current iteration and proceeds to the next iteration.

```moonbit
fn main {
  let mut i = 5
  while i > 0 {
    i = i - 1
    if i == 4 {
      continue
    }
    if i == 1 {
      break
    }
    println(i)
  }
}
```

```default
3
2
```

The `while` loop also supports an optional `nobreak` clause. When the loop condition becomes false, the `nobreak` clause will be executed, and then the loop will end.

```moonbit
fn main {
  let mut i = 2
  while i > 0 {
    println(i)
    i = i - 1
  } nobreak {
    println(i)
  }
}
```

```default
2
1
0
```

When there is an `nobreak` clause, the `while` loop can also return a value. The return value is the evaluation result of the `nobreak` clause. In this case, if you use `break` to exit the loop, you need to provide a return value after `break`, which should be of the same type as the return value of the `nobreak` clause.

```moonbit
fn main {
  let mut i = 10
  let r = while i > 0 {
    i = i - 1
    if i % 2 == 0 {
      break 5
    }
  } nobreak {
    7
  }
  println(r)
}
```

```default
5
```

```moonbit
fn main {
  let mut i = 10
  let r = while i > 0 {
    i = i - 1
  } nobreak {
    7
  }
  println(r)
}
```

```default
7
```

#### For Loop

MoonBit also supports C-style For loops. The keyword `for` is followed by variable initialization clauses, loop conditions, and update clauses separated by semicolons. They do not need to be enclosed in parentheses.
For example, the code below creates a new variable binding `i`, which has a scope throughout the entire loop and is immutable. This makes it easier to write clear code and reason about it:

```moonbit
fn main {
  for i = 0; i < 5; i = i + 1 {
    println(i)
  }
}
```

```default
0
1
2
3
4
```

The variable initialization clause can create multiple bindings:

```moonbit
for i = 0, j = 0; i + j < 100; i = i + 1, j = j + 1 {
  println(i)
}
```

It should be noted that in the update clause, when there are multiple binding variables, the semantics are to update them simultaneously. In other words, in the example above, the update clause does not execute `i = i + 1`, `j = j + 1` sequentially, but rather increments `i` and `j` at the same time. Therefore, when reading the values of the binding variables in the update clause, you will always get the values updated in the previous iteration.

Variable initialization clauses, loop conditions, and update clauses are all optional. For example, the following two are infinite loops:

```moonbit
for i = 1; ; i = i + 1 {
  println(i)
}
for ;; {
  println("loop forever")
}
```

The `for` loop also supports `continue`, `break`, and `nobreak` clauses. Like the `while` loop, the `for` loop can also return a value using the `break` and `nobreak` clauses.

The `continue` statement skips the remaining part of the current iteration of the `for` loop (including the update clause) and proceeds to the next iteration. The `continue` statement can also update the binding variables of the `for` loop, as long as it is followed by expressions that match the number of binding variables, separated by commas.

For example, the following program calculates the sum of even numbers from 1 to 6:

```moonbit
fn main {
  let sum = for i = 1, acc = 0; i <= 6; i = i + 1 {
    if i % 2 == 0 {
      println("even: \{i}")
      continue i + 1, acc + i
    }
  } nobreak {
    acc
  }
  println(sum)
}
```

```default
even: 2
even: 4
even: 6
12
```

#### `for .. in` loop

MoonBit supports traversing elements of different data structures and sequences via the `for .. in` loop syntax:

```moonbit
for x in [1, 2, 3] {
  println(x)
}
```

`for .. in` loop is translated to the use of `Iter` in MoonBit's standard library. Any type with a method `.iter() : Iter[T]` can be traversed using `for .. in`.
For more information of the `Iter` type, see [Iterator]() below.

`for .. in` loop also supports iterating through a sequence of integers, such as:

```moonbit
test {
  let mut i = 0
  for j in 0..<10 {
    i += j
  }
  assert_eq(i, 45)
  let mut k = 0
  for l in 0..<=10 {
    k += l
  }
  assert_eq(k, 55)
}
```

In addition to sequences of a single value, MoonBit also supports traversing sequences of two values, such as `Map`, via the `Iter2` type in MoonBit's standard library.
Any type with method `.iter2() : Iter2[A, B]` can be traversed using `for .. in` with two loop variables:

```moonbit
for k, v in { "x": 1, "y": 2, "z": 3 } {
  println(k)
  println(v)
}
```

Another example of `for .. in` with two loop variables is traversing an array while keeping track of array index:

```moonbit
fn main {
  for index, elem in [4, 5, 6] {
    let i = index + 1
    println("The \{i}-th element of the array is \{elem}")
  }
}
```

```default
The 1-th element of the array is 4
The 2-th element of the array is 5
The 3-th element of the array is 6
```

Control flow operations such as `return`, `break` and error handling are supported in the body of `for .. in` loop:

```moonbit
fn main {
  let map = { "x": 1, "y": 2, "z": 3, "w": 4 }
  for k, v in map {
    if k == "y" {
      continue
    }
    println("\{k}, \{v}")
    if k == "z" {
      break
    }
  }
}
```

```default
x, 1
z, 3
```

If a loop variable is unused, it can be ignored with `_`.

#### Range expression in `for .. in` loop

`for .. in` loops can also be used with range expressions for iterating over a number range:

```moonbit
fn main {
  for x in 0..<5 {
    println(x)
  }
}
```

```default
0
1
2
3
4
```

There are four kinds of range expressions available in `for .. in` loop:

- `a..<b`: iterate from `a` to `b` in increasing order, excluding `b`
- `a..<=b`: iterate from `a` to `b` in increasing order, including `b`
- `a>..b`: iterate from `a` to `b` in decreasing order, excluding `a`
- `a>=..b`: iterate from `a` to `b` in decreasing  order, including `a`

#### List comprehension

MoonBit supports list comprehension syntax for constructing a collection by
iterating over another collection or range:

```moonbit
let squares = [ for x in 1..<=5 => x * x ]
let even_numbers = [ for x in 0..<100 if x % 2 == 0 => x ]
let labelled = [ for i, x in ["a", "b", "c"] => "\{i}: \{x}" ]
let map = { 1: 2, 2: 4, 3: 8 }
let present = [ for x in [1, 2, 3] if map.get(x) is Some(y) => y ]
```

The syntax is `[ for ... => ... ]`. The part before `=>` follows the same
iteration rules as `for .. in`: one binder uses `Iter`, two binders use `Iter2`,
and range expressions such as `0..<10` are supported. An optional `if` guard
filters elements before evaluating the result expression. Names introduced by
an `is` expression in the guard, such as `y` above, can be used in the result
expression.

The result defaults to `Array[T]` when there is no expected type. When the
expected type is known, a list comprehension can also construct
`FixedArray[T]`, `ReadOnlyArray[T]`, `Iter[T]`, `String`, `Bytes`, or `Json`:

```moonbit
let text : String = [ for x in 0..<3 => (x + 'a').unsafe_to_char() ]
let bytes : Bytes = [ for x in 0..<3 => x.to_byte() ]
let fixed : FixedArray[_] = [ for x in 1..<=3 => x ]
```

List comprehensions also support the normal `for` loop header form. When the
expected type is `Iter[T]`, the loop does not need to terminate, so it can be
used to define infinite sequences:

```moonbit
let fib_numbers : Iter[Int] = [
  for p1 = 1, p2 = 0;; p1 = p1 + p2, p2 = p1 => p1
]
let first_six = fib_numbers.take(6).collect()
```

Control flow operations such as `return`, `break`, and `continue` are not
allowed inside list comprehensions.

#### Labelled Continue/Break

When a loop is labelled, it can be referenced from a `break` or `continue` from
within a nested loop. For example:

```moonbit
test "break label" {
  let mut count = 0
  let xs = [1, 2, 3]
  let ys = [4, 5, 6]
  let res = outer~: for i in xs {
    for j in ys {
      count = count + i
      break outer~ j
    }
  } nobreak {
    -1
  }
  assert_eq(res, 4)
  assert_eq(count, 1)
}

test "continue label" {
  let mut count = 0
  let init = 10
  let res = outer~: for i = init {
    if i == 0 {
      break outer~ 42
    }
    for ;; {
      count = count + 1
      continue outer~ i - 1
    }
  }
  assert_eq(res, 42)
  assert_eq(count, 10)
}
```

#### `defer` expression

`defer` expression can be used to perform reliable resource cleanup.
The syntax for `defer` is as follows:

```moonbit
defer <expr>
<body>
```

Whenever the program leaves `body`, `expr` will be executed.
For example, the following program:

```moonbit
  defer println("perform resource cleanup")
  println("do things with the resource")
```

will first print `do things with the resource`, and then `perform resource cleanup`.
`defer` expression will always get executed no matter how its body exits.
It can handle [error](error-handling.md),
as well as control flow constructs including `return`, `break` and `continue`.

Consecutive `defer` will be executed in reverse order, for example, the following:

```moonbit
  defer println("first defer")
  defer println("second defer")
  println("do things")
```

will output first `do things`, then `second defer`, and finally `first defer`.

`return`, `break` and `continue` are disallowed in the right hand side of `defer`.
Currently, raising error or calling `async` function is also disallowed in the right hand side of `defer`.

### Iterator

An iterator is an object that traverse through a sequence while providing access
to its elements. Traditional OO languages like Java's `Iterator<T>` use `next()`
`hasNext()` to step through the iteration process, whereas functional languages
(JavaScript's `forEach`, Lisp's `mapcar`) provides a high-order function which
takes an operation and a sequence then consumes the sequence with that operation
being applied to the sequence. The former is called *external iterator* (visible
to user) and the latter is called *internal iterator* (invisible to user).

The built-in type `Iter[T]` is MoonBit's external iterator implementation. It
exposes `next()` to pull the next value: it returns `Some(value)` and advances
the iterator, or `None` when the iteration is finished.
Almost all built-in sequential data structures have implemented `Iter`:

```moonbit
///|
fn filter_even(l : Array[Int]) -> Array[Int] {
  let l_iter : Iter[Int] = l.iter()
  l_iter.filter(x => (x & 1) == 0).collect()
}

///|
fn fact(n : Int) -> Int {
  let start = 1
  let range : Iter[Int] = start.until(n)
  range.fold(Int::mul, init=start)
}
```

Commonly used methods include:

- `each`: Iterates over each element in the iterator, applying some function to each element.
- `fold`: Folds the elements of the iterator using the given function, starting with the given initial value.
- `collect`: Collects the elements of the iterator into an array.
- `filter`: *lazy* Filters the elements of the iterator based on a predicate function.
- `map`: *lazy* Transforms the elements of the iterator using a mapping function.
- `concat`: *lazy* Combines two iterators into one by appending the elements of the second iterator to the first.

Methods like `filter` and `map` are very common on a sequence object e.g. Array.
But what makes `Iter` special is that any method that constructs a new `Iter` is
*lazy* (i.e. iteration doesn't start on call because it's wrapped inside a
function), as a result of no allocation for intermediate value. That's what
makes `Iter` superior for traversing through sequence: no extra cost. MoonBit
encourages user to pass an `Iter` across functions instead of the sequence
object itself.

Pre-defined sequence structures like `Array` and its iterators should be
enough to use. But to take advantages of these methods when used with a custom
sequence with elements of type `S`, we will need to implement `Iter`, namely, a function that returns
an `Iter[S]`. Take `Bytes` as an example:

```moonbit
///|
fn iter(data : Bytes) -> Iter[Byte] {
  let mut index = 0
  Iter::new(fn() -> Byte? {
    if index < data.length() {
      let byte = data[index]
      index += 1
      Some(byte)
    } else {
      None
    }
  })
}
```

Iterators are single-pass: once you call `next()` or consume them with methods
like `each`, `fold`, or `collect`, their internal state advances and cannot be
reset. If you need to traverse the sequence again, request a new `Iter` from
the source.

### Custom Data Types

There are two ways to create new data types: `struct` and `enum`.

#### Struct

In MoonBit, structs are similar to tuples, but their fields are indexed by field names. A struct can be constructed using a struct literal, which is composed of a set of labeled values and delimited with curly brackets. The type of a struct literal can be automatically inferred if its fields exactly match the type definition. A field can be accessed using the dot syntax `s.f`. If a field is marked as mutable using the keyword `mut`, it can be assigned a new value.

```moonbit
struct User {
  id : Int
  name : String
  mut email : String
}
```

```moonbit
fn main {
  let u = User::{ id: 0, name: "John Doe", email: "john@doe.com" }
  u.email = "john@doe.name"
  //! u.id = 10
  println(u.id)
  println(u.name)
  println(u.email)
}
```

```default
0
John Doe
john@doe.name
```

##### Constructing Struct with Shorthand

If you already have some variable like `name` and `email`, it's redundant to repeat those names when constructing a struct. You can use shorthand instead, it behaves exactly the same:

```moonbit
let name = "john"
let email = "john@doe.com"
let u = User::{ id: 0, name, email }
```

If there's no other struct that has the same fields, it's redundant to add the struct's name when constructing it:

```moonbit
let u2 = { id: 0, name, email }
```

##### Struct Update Syntax

It's useful to create a new struct based on an existing one, but with some fields updated.

```moonbit
fn main {
  let user = { id: 0, name: "John Doe", email: "john@doe.com" }
  let updated_user = { ..user, email: "john@doe.name" }
  println(
    (
      $|{ id: \{user.id}, name: \{user.name}, email: \{user.email} }
      $|{ id: \{updated_user.id}, name: \{updated_user.name}, email: \{updated_user.email} }
    ),
  )
}
```

```default
{ id: 0, name: John Doe, email: john@doe.com }
{ id: 0, name: John Doe, email: john@doe.name }
```

##### Custom constructor for struct

MoonBit also supports defining a custom constructor for every `struct` type.
A constructor is a special method that can be called with the name of the
struct to create a value. First define the struct as usual:

```moonbit
struct IntBox {
  value : Int
} derive(Debug)
```

The constructor should then be implemented as a method whose name is the same as
the struct type. Its return value must be the struct itself:

```moonbit
fn IntBox::IntBox(value : Int) -> IntBox {
  { value, }
}
```

If a `struct` declares a constructor, it can be constructed by name directly:

```moonbit
  let box = IntBox(10)
  debug_inspect(box, content="{ value: 10 }")
```

The constructor call follows the constructor method signature, so unlabeled
parameters can be written in the familiar `TypeName(value)` form.

Constructors may also use labeled and optional arguments, just like normal functions:

```moonbit
struct StructWithConstr {
  x : Int
  y : Int
} derive(Debug)
```

```moonbit
fn StructWithConstr::StructWithConstr(x~ : Int, y? : Int = x) -> StructWithConstr {
  { x, y }
}
```

```moonbit
  let s = StructWithConstr(x=1)
  debug_inspect(s, content="{ x: 1, y: 1 }")
```

Because struct constructors are implemented by normal functions, they may raise errors:

```moonbit
suberror BuildError {
  NegativeInput
} derive(Debug)

struct Positive {
  value : Int
} derive(Debug)
```

```moonbit
fn Positive::Positive(x : Int) -> Positive raise BuildError {
  guard x >= 0 else { raise NegativeInput }
  { value: x }
}
```

```moonbit
  debug_inspect(try? Positive(10), content="Ok({ value: 10 })")
  debug_inspect(try? Positive(-1), content="Err(NegativeInput)")
```

Asynchronous constructors are declared with `async fn TypeName::TypeName` and
can be used inside async code:

```moonbit
struct AsyncBox {
  value : Int
} derive(Debug)
```

```moonbit
async fn AsyncBox::AsyncBox(x : Int) -> AsyncBox {
  @async.sleep(0)
  { value: x }
}
```

```moonbit
async test "struct constructor async" {
  let box = AsyncBox(10)
  debug_inspect(box, content="{ value: 10 }")
}
```

Creating value via `struct` constructor has exactly the same semantic as
[enum constructors](),
except that `struct` constructors cannot be used for pattern matching.
For example, when creating a foreign `struct` using constructors,
the package name can be omitted if the expected type of the expression is known.

Since `struct` constructors are implemented by normal functions,
they may [raise error](error-handling.md) or [perform asynchronous operations](async-experimental.md).
`struct` constructors also support [optional arguments]().
Default values for optional arguments are written on the constructor
implementation, just like normal function signatures.

#### Enum

Enum types are similar to algebraic data types in functional languages. Users familiar with C/C++ may prefer calling it tagged union.

An enum can have a set of cases (constructors). Constructor names must start with capitalized letter. You can use these names to construct corresponding cases of an enum, or checking which branch an enum value belongs to in pattern matching:

```moonbit
/// An enum type that represents the ordering relation between two values,
/// with three cases "Smaller", "Greater" and "Equal"
enum Relation {
  Smaller
  Greater
  Equal
}
```

```moonbit
/// compare the ordering relation between two integers
fn compare_int(x : Int, y : Int) -> Relation {
  if x < y {
    // when creating an enum, if the target type is known, 
    // you can write the constructor name directly
    Smaller
  } else if x > y {
    // but when the target type is not known,
    // you can always use `TypeName::Constructor` to create an enum unambiguously
    Relation::Greater
  } else {
    Equal
  }
}

/// output a value of type `Relation`
fn print_relation(r : Relation) -> Unit {
  // use pattern matching to decide which case `r` belongs to
  match r {
    // during pattern matching, if the type is known, 
    // writing the name of constructor is sufficient
    Smaller => println("smaller!")
    // but you can use the `TypeName::Constructor` syntax 
    // for pattern matching as well
    Relation::Greater => println("greater!")
    Equal => println("equal!")
  }
}
```

```moonbit
fn main {
  print_relation(compare_int(0, 1))
  print_relation(compare_int(1, 1))
  print_relation(compare_int(2, 1))
}
```

```default
smaller!
equal!
greater!
```

Enum cases can also carry payload data. Here's an example of defining an integer list type using enum:

```moonbit
enum Lst {
  Nil
  // constructor `Cons` carries additional payload: the first element of the list,
  // and the remaining parts of the list
  Cons(Int, Lst)
}
```

```moonbit
// In addition to binding payload to variables,
// you can also continue matching payload data inside constructors.
// Here's a function that decides if a list contains only one element
fn is_singleton(l : Lst) -> Bool {
  match l {
    // This branch only matches values of shape `Cons(_, Nil)`, 
    // i.e. lists of length 1
    Cons(_, Nil) => true
    // Use `_` to match everything else
    _ => false
  }
}

fn print_list(l : Lst) -> Unit {
  // when pattern-matching an enum with payload,
  // in additional to deciding which case a value belongs to
  // you can extract the payload data inside that case
  match l {
    Nil => println("nil")
    // Here `x` and `xs` are defining new variables 
    // instead of referring to existing variables,
    // if `l` is a `Cons`, then the payload of `Cons` 
    // (the first element and the rest of the list)
    // will be bind to `x` and `xs
    Cons(x, xs) => {
      println("\{x},")
      print_list(xs)
    }
  }
}
```

```moonbit
fn main {
  // when creating values using `Cons`, the payload of by `Cons` must be provided
  let l : Lst = Cons(1, Cons(2, Nil))
  println(is_singleton(l))
  print_list(l)
}
```

```default
false
1,
2,
nil
```

##### Constructor with labelled arguments

Enum constructors can have labelled argument:

```moonbit
enum E {
  // `x` and `y` are labelled argument
  C(x~ : Int, y~ : Int)
}
```

```moonbit
// pattern matching constructor with labelled arguments
fn f(e : E) -> Unit {
  match e {
    // `label=pattern`
    C(x=0, y=0) => println("0!")
    // `x~` is an abbreviation for `x=x`
    // Unmatched labelled arguments can be omitted via `..`
    C(x~, ..) => println(x)
  }
}
```

```moonbit
fn main {
  f(C(x=0, y=0))
  let x = 0
  f(C(x~, y=1)) // <=> C(x=x, y=1)
}
```

```default
0!
0
```

It is also possible to access labelled arguments of constructors like accessing struct fields in pattern matching:

```moonbit
enum Object {
  Point(x~ : Double, y~ : Double)
  Circle(x~ : Double, y~ : Double, radius~ : Double)
}

suberror NotImplementedError derive(Debug)

fn Object::distance_with(
  self : Object,
  other : Object,
) -> Double raise NotImplementedError {
  match (self, other) {
    // For variables defined via `Point(..) as p`,
    // the compiler knows it must be of constructor `Point`,
    // so you can access fields of `Point` directly via `p.x`, `p.y` etc.
    (Point(_) as p1, Point(_) as p2) => {
      let dx = p2.x - p1.x
      let dy = p2.y - p1.y
      (dx * dx + dy * dy).sqrt()
    }
    (Point(_), Circle(_)) | (Circle(_), Point(_)) | (Circle(_), Circle(_)) =>
      raise NotImplementedError
  }
}
```

```moonbit
fn main {
  let p1 : Object = Point(x=0, y=0)
  let p2 : Object = Point(x=3, y=4)
  let c1 : Object = Circle(x=0, y=0, radius=2)
  try {
    println(p1.distance_with(p2))
    println(p1.distance_with(c1))
  } catch {
    _ => println("NotImplementedError")
  }
}
```

```default
5
NotImplementedError
```

##### Constructor with mutable fields

It is also possible to define mutable fields for constructor. This is especially useful for defining imperative data structures:

```moonbit
// A set implemented using mutable binary search tree.
struct Set[X] {
  mut root : Tree[X]
}

fn[X : Compare] Set::insert(self : Set[X], x : X) -> Unit {
  self.root = self.root.insert(x, parent=Nil)
}

// A mutable binary search tree with parent pointer
enum Tree[X] {
  Nil
  // only labelled arguments can be mutable
  Node(
    mut value~ : X,
    mut left~ : Tree[X],
    mut right~ : Tree[X],
    mut parent~ : Tree[X]
  )
}

// In-place insert a new element to a binary search tree.
// Return the new tree root
fn[X : Compare] Tree::insert(
  self : Tree[X],
  x : X,
  parent~ : Tree[X],
) -> Tree[X] {
  match self {
    Nil => Node(value=x, left=Nil, right=Nil, parent~)
    Node(_) as node => {
      let order = x.compare(node.value)
      if order == 0 {
        // mutate the field of a constructor
        node.value = x
      } else if order < 0 {
        // cycle between `node` and `node.left` created here
        node.left = node.left.insert(x, parent=node)
      } else {
        node.right = node.right.insert(x, parent=node)
      }
      // The tree is non-empty, so the new root is just the original tree
      node
    }
  }
}
```

##### Extensible enum

An `extenum` defines an open enum type. Unlike a regular `enum`, an
`extenum` can receive more constructors later, including from another package.
This is useful when a package wants to define the shared event, message, or
extension-point type, while other packages contribute their own cases.

```moonbit
pub(all) extenum LogEvent[T] {
  Info(T)
}
```

Use `extenum Type += { ... }` to add constructors to an extensible enum in the
same package:

```moonbit
pub(all) extenum LogEvent[T] += {
  Warning(T)
  Critical(T, T)
}
```

To extend an extensible enum from another package, qualify the target type with
the package that defines the type:

```moonbit
pub(all) extenum @base.LogEvent[T] += {
  Debug(T)
}
```

Extensible enum constructors are qualified by the package that defines the
constructor. For constructors from the current package, use the constructor name
directly when the expected type is known. For constructors from another
package, use `@pkg.Constructor` in expressions and patterns. When you want to
make both the extensible enum type and the constructor origin explicit, write
the constructor as `@type_pkg.Type::@constructor_pkg.Constructor`.

When a package imports both the base package and an extension package, values
from both packages have the same extensible enum type:

```moonbit
pub fn describe(event : @base.LogEvent[String]) -> String {
  match event {
    @base.Info(message) => "info: \{message}"
    @base.Warning(message) => "warning: \{message}"
    @base.Critical(code, message) => "critical \{code}: \{message}"
    @plugin.Debug(message) => "debug: \{message}"
    _ => "unknown"
  }
}

pub fn debug_event(message : String) -> @base.LogEvent[String] {
  @plugin.Debug(message)
}

pub fn qualified_debug_event(message : String) -> @base.LogEvent[String] {
  @base.LogEvent::@plugin.Debug(message)
}
```

Pattern matching must include a wildcard branch, because more constructors
can be added outside the current declaration.

Only `extenum` declarations can be extended. Regular `enum` declarations are
closed.

#### Tuple Struct

MoonBit supports a special kind of struct called tuple struct:

```moonbit
struct UserId(Int)

struct UserInfo(UserId, String)
```

Tuple structs are similar to enum with only one constructor (with the same name as the tuple struct itself). So, you can use the constructor to create values, or use pattern matching to extract the underlying representation:

```moonbit
fn main {
  let id : UserId = UserId(1)
  let name : UserInfo = UserInfo(id, "John Doe")
  let UserId(uid) = id // uid : Int
  let UserInfo(_, uname) = name // uname: String
  println(uid)
  println(uname)
}
```

```default
1
John Doe
```

Besides pattern matching, you can also use index to access the elements similar to tuple:

```moonbit
fn main {
  let id : UserId = UserId(1)
  let info : UserInfo = UserInfo(id, "John Doe")
  let uid : Int = id.0
  let uname : String = info.1
  println(uid)
  println(uname)
}
```

```default
1
John Doe
```

#### Type alias

MoonBit supports type alias via the syntax `type NewType = OldType`:

##### WARNING
The old syntax `typealias OldType as NewType` may be removed in the future.

```moonbit
pub type Index = Int
pub type MyIndex = Int
pub type MyMap = Map[Int, String]
```

Unlike all other kinds of type declaration above, type alias does not define a new type,
it is merely a type macro that behaves exactly the same as its definition.
So for example one cannot define new methods or implement traits for a type alias.

#### Local types

MoonBit supports declaring structs/enums at the top of a toplevel
function, which are only visible within the current toplevel function. These
local types can use the generic parameters of the toplevel function but cannot
introduce additional generic parameters themselves. Local types can derive
methods using derive, but no additional methods can be defined manually. For
example:

```moonbit
fn[T : Debug] toplevel(x : T) -> Unit {
  enum LocalEnum {
    A(T)
    B(Int)
  } derive(Debug)
  struct LocalStruct {
    a : (String, T)
  } derive(Debug)
  struct LocalStructTuple(T) derive(Debug)
  ...
}
```

Currently, local types do not support being declared as error types.

### Pattern Matching

Pattern matching allows us to match on specific pattern and bind data from data structures.

#### Simple Patterns

We can pattern match expressions against

- literals, such as boolean values, numbers, chars, strings, etc
- constants
- structs
- enums
- arrays
- maps
- JSONs

and so on. We can define identifiers to bind the matched values so that they can be used later.

```moonbit
const ONE = 1

fn match_int(x : Int) -> Unit {
  match x {
    0 => println("zero")
    ONE => println("one")
    value => println(value)
  }
}
```

We can use `_` as wildcards for the values we don't care about, and use `..` to ignore remaining fields of struct or enum, or array (see [array pattern]()).

```moonbit
struct Point3D {
  x : Int
  y : Int
  z : Int
}

fn match_point3D(p : Point3D) -> Unit {
  match p {
    { x: 0, .. } => println("on yz-plane")
    _ => println("not on yz-plane")
  }
}

enum Point[T] {
  Point2D(Int, Int, name~ : String, payload~ : T)
}

fn[T] match_point(p : Point[T]) -> Unit {
  match p {
    //! Point2D(0, 0) => println("2D origin")
    Point2D(0, 0, ..) => println("2D origin")
    Point2D(_) => println("2D point")
    _ => panic()
  }
}
```

We can use `as` to give a name to some pattern, and we can use `|` to match several cases at once. A variable name can only be bound once in a single pattern, and the same set of variables should be bound on both sides of `|` patterns.

```moonbit
match expr {
  //! Add(e1, e2) | Lit(e1) => ...
  Lit(n) as a => ...
  Add(e1, e2) | Mul(e1, e2) => ...
  ...
}
```

#### Array Pattern

Array patterns can be used to match on the following types to obtain their
corresponding elements or views:

| Type                                  | Element   | View         |
|---------------------------------------|-----------|--------------|
| Array[T], ArrayView[T], FixedArray[T] | T         | ArrayView[T] |
| Bytes, BytesView                      | Byte      | BytesView    |
| String, StringView                    | Char      | StringView   |

Array patterns have the following forms:

- `[]` : matching for empty array
- `[pa, pb, pc]` : matching for array of length three, and bind `pa`, `pb`, `pc`
  to the three elements
- `[pa, ..rest, pb]` : matching for array with at least two elements, and bind
  `pa` to the first element, `pb` to the last element, and `rest` to the
  remaining elements. the binder `rest` can be omitted if the rest of the
  elements are not needed. Arbitrary number of elements are allowed preceding
  and following the `..` part. Because `..` can match uncertain number of
  elements, it can appear at most once in an array pattern.

```moonbit
test {
  let ary = [1, 2, 3, 4]
  if ary is [a, b, .. rest] && a == 1 && b == 2 && rest.length() == 2 {
    inspect("a = \{a}, b = \{b}", content="a = 1, b = 2")
  } else {
    fail("")
  }
  guard ary is [.., a, b] else { fail("") }
  inspect("a = \{a}, b = \{b}", content="a = 3, b = 4")
}
```

Array patterns provide a unicode-safe way to manipulate strings, meaning that it
respects the code unit boundaries. For example, we can check if a string is a
palindrome:

```moonbit
test {
  fn palindrome(s : String) -> Bool {
    for view = s.view() {
      match view {
        [] | [_] => break true
        [a, .. rest, b] => if a == b { continue rest } else { break false }
      }
    }
  }

  inspect(palindrome("abba"), content="true")
  inspect(palindrome("中b中"), content="true")
  inspect(palindrome("文bb中"), content="false")
}
```

When there are consecutive char or byte constants in an array pattern, the
pattern spread `..` operator can be used to combine them to make the code look
cleaner. Note that in this case the `..` followed by string or bytes constant
matches exact number of elements so its usage is not limited to once.

```moonbit
const NO : Bytes = b"no"

test {
  fn match_string(s : String) -> Bool {
    match s {
      [.. "yes", ..] => true // equivalent to ['y', 'e', 's', ..]
    }
  }

  fn match_bytes(b : Bytes) -> Bool {
    match b {
      [.. NO, ..] => false // equivalent to ['n', 'o', ..]
    }
  }
}
```

#### Bitstring Pattern

Bitstring patterns can match packed bit fields from byte containers. They are
supported on `BytesView`, `Bytes`, `Array[Byte]`, `FixedArray[Byte]`,
`ReadOnlyArray[Byte]`, and `ArrayView[Byte]`. Use explicit widths with
`be`/`le` suffixes to make endianness clear.
`be` supports widths 1..64; `le` is only defined for byte-aligned widths (8 \*
n), since little-endian order is defined on bytes. Without `..`, the pattern
must consume the entire view.

```moonbit
test {
  let packet : Bytes = b"\xD2\x10\x7F"
  let header : BytesView = packet[0:2]
  let (flag, kind, version, length) = match header {
    [u1be(flag), u3be(kind), u4be(version), u8be(length)] =>
      (flag, kind, version, length)
    _ => fail("bad header")
  }
  assert_eq(flag, 1)
  assert_eq(kind, 0b101)
  assert_eq(version, 0b0010)
  assert_eq(length, 16)
}
```

Use literal bit patterns to validate headers, and `..` to capture the remaining
data for the next parse step.

```moonbit
test {
  let data : Bytes = b"\xF1\xAA\xBB"
  let view : BytesView = data[0:]
  let tag = match view {
    [u4be(0b1111), u4be(tag), .. rest] => {
      assert_eq(rest, b"\xAA\xBB"[0:])
      tag
    }
    _ => fail("bad prefix")
  }
  assert_eq(tag, 0b0001)
}
```

Examples over common byte containers (note the `MutArrayView` slice):

```moonbit
test {
  let b : Bytes = b"\x80"
  guard b is [u1be(1), ..] else { fail("Bytes") }

  let a : Array[Byte] = [b'\x80']
  guard a is [u1be(1), ..] else { fail("Array[Byte]") }

  let f : FixedArray[Byte] = [b'\x80']
  guard f is [u1be(1), ..] else { fail("FixedArray[Byte]") }

  let r : ReadOnlyArray[Byte] = [b'\x80']
  guard r is [u1be(1), ..] else { fail("ReadOnlyArray[Byte]") }

  let v : ArrayView[Byte] = a[:]
  guard v is [u1be(1), ..] else { fail("ArrayView[Byte]") }

  let mv : MutArrayView[Byte] = a.mut_view()
  guard mv[:] is [u1be(1), ..] else { fail("MutArrayView[Byte]") }
}
```

Signed patterns use two's-complement semantics. For example, `u1be` yields `0`
or `1`, while `i1be` yields `0` or `-1`:

```moonbit
test {
  let bytes = b"\x80"
  let u : UInt = match bytes[:] {
    [u1be(u), ..] => u
    _ => fail("u1be")
  }
  let i : Int = match bytes[:] {
    [i1be(i), ..] => i
    _ => fail("i1be")
  }
  assert_eq(u, 1U)
  assert_eq(i, -1)
}
```

Result types depend on width:

| Width                | Result type    |
|----------------------|----------------|
| 1..32 bits (`u`/`i`) | `UInt` / `Int` |
| 33..64 bits (`u`)    | `UInt64`       |
| 33..64 bits (`i`)    | `Int64`        |

#### Range Pattern

For builtin integer types and `Char`, MoonBit allows matching whether the value falls in a specific range.

Range patterns have the form `a..<b` or `a..=b`, where `..<` means the upper bound is exclusive, and `..=` means inclusive upper bound.
`a` and `b` can be one of:

- literal
- named constant declared with `const`
- `_`, meaning the pattern has no restriction on this side

Here are some examples:

```moonbit
const Zero = 0

fn sign(x : Int) -> Int {
  match x {
    _..<Zero => -1
    Zero => 0
    1..<_ => 1
  }
}

fn classify_char(c : Char) -> String {
  match c {
    'a'..='z' => "lowercase"
    'A'..='Z' => "uppercase"
    '0'..='9' => "digit"
    _ => "other"
  }
}
```

#### Map Pattern

MoonBit allows convenient matching on map-like data structures.
Inside a map pattern, the `key : value` syntax will match if `key` exists in the map, and match the value of `key` with pattern `value`.
The `key? : value` syntax will match no matter `key` exists or not, and `value` will be matched against `map[key]` (an optional).

```moonbit
match map {
  // matches if any only if "b" exists in `map`
  { "b": _, .. } => ...
  // matches if and only if "b" does not exist in `map` and "a" exists in `map`.
  // When matches, bind the value of "a" in `map` to `x`
  { "b"? : None, "a": x, .. } => ...
  // compiler reports missing case: { "b"? : None, "a"? : None }
}
```

- To match a data type `T` using map pattern, `T` must have a method `get(Self, K) -> Option[V]` for some type `K` and `V` (see [method and trait](methods.md)).
- Currently, the key part of map pattern must be a literal or constant
- Map patterns are always open: the unmatched keys are silently ignored, and `..` needs to be added to identify this nature
- Map pattern will be compiled to efficient code: every key will be fetched at most once

#### Json Pattern

When the matched value has type `Json`, literal patterns can be used directly, together with constructors:

```moonbit
match json {
  { "version": "1.0.0", "import": [..] as imports, .. } => ...
  { "version": Number(i, ..), "import": Array(imports), .. } => ...
  ...
}
```

#### Guard condition

Each case in a pattern matching expression can have a guard condition. A guard
condition is a boolean expression that must be true for the case to be matched.
If the guard condition is false, the case is skipped and the next case is tried.
For example:

```moonbit
fn guard_cond(x : Int?) -> Int {
  fn f(x : Int) -> Array[Int] {
    [x, x + 42]
  }

  match x {
    Some(a) if f(a) is [0, b] => a + b
    Some(b) => b
    None => -1
  }
}

test {
  assert_eq(guard_cond(None), -1)
  assert_eq(guard_cond(Some(0)), 42)
  assert_eq(guard_cond(Some(1)), 1)
}
```

Note that the guard conditions will not be considered when checking if all
patterns are covered by the match expression. So you will see a warning of
partial match for the following case:

```moonbit
fn guard_check(x : Int?) -> Unit {
  match x {
    Some(a) if a >= 0 => ()
    Some(a) if a < 0 => ()
    None => ()
  }
}
```

##### WARNING
It is not encouraged to call a function that mutates a part of the value being
matched inside a guard condition. When such case happens, the part being mutated
will not be re-evaluated in the subsequent patterns. Use it with caution.

### Generics

Generics are supported in top-level function and data type definitions. Type parameters can be introduced within square brackets. We can rewrite the aforementioned data type `List` to add a type parameter `T` to obtain a generic version of lists. We can then define generic functions over lists like `map` and `reduce`.

```moonbit
///|
enum List[T] {
  Nil
  Cons(T, List[T])
}

///|
fn[S, T] List::map(self : List[S], f : (S) -> T) -> List[T] {
  match self {
    Nil => Nil
    Cons(x, xs) => Cons(f(x), xs.map(f))
  }
}

///|
fn[S, T] List::reduce(self : List[S], op : (T, S) -> T, init : T) -> T {
  match self {
    Nil => init
    Cons(x, xs) => xs.reduce(op, op(init, x))
  }
}
```

### Special Syntax

#### Pipelines

MoonBit provides convenient pipe syntaxes `x |> f(y)` and `f <| x`, which can be used to chain regular function calls or make nested builder-style code easier to read:

```moonbit
5 |> ignore // <=> ignore(5)
[] |> Array::push(5) // <=> Array::push([], 5)
1
|> add(5) // <=> add(1, 5)
|> x => { x + 1 }
|> ignore // <=> ignore(add(1, 5))
```

The MoonBit code follows the *data-first* style, meaning the function places its "subject" as the first argument.
Thus, the pipe operator inserts the left-hand side value into the first argument of the right-hand side function call by default.
For example, `x |> f(y)` is equivalent to `f(x, y)`.

You can use the `_` operator to insert `x` into any argument of the function `f`, such as `x |> f(y, _)`, which is equivalent to `f(y, x)`. Labeled arguments are also supported.

The pipe operator can also connect to an arrow function. When piping into an arrow function, the function body must be wrapped in curly braces, for example `value |> x => { x + 1 }`.

The reverse pipe operator applies the right-hand side as the final argument of the left-hand side call. For example, `f <| x` is equivalent to `f(x)`, and `f(a, b) <| c` is equivalent to `f(a, b, c)`. This is especially useful for DSL-like code, since nested calls such as `div([text("hello")])` can instead be written as `div <| [text <| "hello"]`.

```moonbit
let page = div <| [
    text <| "hello",
    section("toolbar") <| fn() { [text <| "save", text <| "cancel"] },
  ]
inspect(
  page,
  content="div(text(hello), toolbar: div(text(save), text(cancel)))",
)
```

Because reverse pipe attaches the final argument, it also works well with functions whose last argument is a lambda, enabling a trailing-lambda style such as `section("toolbar") <| fn () { ... }`.

#### Cascade Operator

The cascade operator `..` is used to perform a series of mutable operations on
the same value consecutively. The syntax is as follows:

```moonbit
let arr = []..append([1])
```

Here, `x..f()` is equivalent to `{ x.f(); x }`.

Consider the following scenario: for a `StringBuilder` type that has methods
like `write_string`, `write_char`, `write_object`, etc., we often need to perform
a series of operations on the same `StringBuilder` value:

```moonbit
let builder = StringBuilder::new()
builder.write_char('a')
builder.write_char('a')
builder.write_object(1001)
builder.write_string("abcdef")
let result = builder.to_string()
```

To avoid repetitive typing of `builder`, its methods are often designed to
return `self` itself, allowing operations to be chained using the `.` operator.
To distinguish between immutable and mutable operations, in MoonBit,
for all methods that return `Unit`, cascade operator can be used for
consecutive operations without the need to modify the return type of the methods.

```moonbit
let result = StringBuilder::new()
  ..write_char('a')
  ..write_char('a')
  ..write_object(1001)
  ..write_string("abcdef")
  .to_string()
```

#### is Expression

The `is` expression tests whether a value conforms to a specific pattern. It
returns a `Bool` value and can be used anywhere a boolean value is expected,
for example:

```moonbit
fn[T] is_none(x : T?) -> Bool {
  x is None
}

fn start_with_lower_letter(s : String) -> Bool {
  s is ['a'..='z', ..]
}
```

Pattern binders introduced by `is` expressions can be used in the following
contexts:

1. In boolean AND expressions (`&&`):
   binders introduced in the left-hand expression can be used in the right-hand
   expression
   ```moonbit
   fn f(x : Int?) -> Bool {
     x is Some(v) && v >= 0
   }
   ```
2. In the first branch of `if` expression: if the condition is a sequence of
   boolean expressions `e1 && e2 && ...`, the binders introduced by the `is`
   expression can be used in the branch where the condition evaluates to `true`.
   ```moonbit
   fn g(x : Array[Int?]) -> Unit {
     if x is [v, .. rest] && v is Some(i) && i is (0..=10) {
       debug(v)
       println(i)
       debug(rest)
     }
   }
   ```
3. In the following statements of a `guard` condition:
   ```moonbit
   fn h(x : Int?) -> Unit {
     guard x is Some(v)
     println(v)
   }
   ```
4. In the body of a `while` loop:
   ```moonbit
   fn i(x : Int?) -> Unit {
     let mut m = x
     while m is Some(v) {
       println(v)
       m = None
     }
   }
   ```

Note that `is` expression can only take a simple pattern. If you need to use
`as` to bind the pattern to a variable, you have to add parentheses. For
example:

```moonbit
fn j(x : Int) -> Int? {
  Some(x)
}

fn init {
  guard j(42) is (Some(a) as b)
  println(a)
  debug(b)
}
```

#### Regex Literal Expression

`re"..."` is a regex literal expression. Its type is `Regex`.

Regex literals are ordinary expressions, so they can be stored in local
bindings, passed as arguments, used as default argument values, and defined as
constants:

```moonbit
let r : Regex = re"a(b+)"
const IDENT_START : Regex = re"[A-Za-z_]"
const IDENT : Regex = IDENT_START + re"[A-Za-z0-9_]*"
```

Regex values can also be combined with `+` for sequence and `|` for
alternation. In places that require a regex constant expression, such as
[`=~`](), named `const` values defined from regex
literals can be referenced directly.

Unlike ordinary string literals, regex literals do not require double-escaping
backslashes. For example, write `re"/\*"` instead of `re"/\\*"`.

```moonbit
const REGEX_IDENT_START = re"[A-Za-z_]"

const REGEX_IDENT_CONT = re"[A-Za-z0-9_]*"

const REGEX_AB : Regex = re"a" + re"b"

fn regex_default_arg(re? : Regex = re"abc") -> Bool {
  re.execute("zabc") is Some(_)
}

test {
  let regex : Regex = re"a(b+)"
  assert_true(regex.execute("abbb") is Some(_))
  assert_true(regex.execute("ac") is None)

  assert_true(REGEX_AB.execute("ab") is Some(_))
  assert_true(REGEX_AB.execute("ac") is None)
  assert_true(regex_default_arg())
}
```

Invalid regex literals are rejected at compile time.

Regex literals use MoonBit's regex syntax. The supported forms include:

- Literal characters: ordinary characters match themselves
- Wildcard: `.` matches any single character, including newline
- Character classes: `[abc]`, `[^abc]`, `[a-z]`
- POSIX classes inside character classes: `[[:digit:]]`, `[[:alpha:]]`,
  `[[:space:]]`, `[[:word:]]`, `[[:xdigit:]]`, etc.
- Quantifiers: `*`, `+`, `?`, `{n}`, `{n,}`, `{n,m}`
- Non-greedy quantifiers: `*?`, `+?`, `??`, `{n}?`, `{n,}?`, `{n,m}?`
- Grouping and alternation: `( ... )`, `(?: ... )`, `(?<name> ... )`, `a|b`
- Assertions: `^`, `$`, `\b`, `\B`
- Scoped modifier: `(?i: ... )` for case-insensitive matching

Escape handling is regex-oriented rather than string-oriented. Common escapes
include `\n`, `\r`, `\t`, `\f`, `\v`, escaped metacharacters such as `\.` and
`\(`, and Unicode escapes `\uXXXX` / `\u{X...}`. To match a literal `{`, use
`[{]` rather than `\{`. This leaves room for future interpolation support in
regex literals, where `\{` would conflict with the interpolation syntax.

There are several important semantics and restrictions:

- `^` and `$` are non-multiline anchors: they match only the beginning and end
  of the whole input
- `\b` and `\B` are currently usable when a regex literal is handled as a
  first-class `Regex` value
  They are not currently available in `regex match expression` constant
  contexts such as [`=~`](), but this restriction is
  expected to be relaxed in the future
- POSIX character classes are ASCII-based
- `\d`, `\D`, `\s`, `\S`, `\w`, and `\W` are not supported
  Use `[[:digit:]]`, `[^[:digit:]]`, `[[:space:]]`, `[^[:space:]]`,
  `[[:word:]]`, and `[^[:word:]]` instead
- `\xHH` byte escapes are not supported in `re"..."`; use Unicode escapes or
  ordinary characters instead
- Lookahead, lookbehind, backreferences, and character-class set operations are
  not supported
- In character classes, `-` is used for ranges
  To match a literal dash, escape it as `\-`; putting `-` at the start or end
  of a character class is not supported

Named capture groups such as `(?<id>[0-9]+)` belong to the `Regex` value
itself. They are useful with APIs such as `Regex::execute` and
`MatchResult::named_group`, but they do not introduce MoonBit binders by
themselves.

When a regex literal is used as a first-class `Regex` value, operations such
as `Regex::execute` use first-match semantics: they return the first match
found from the search position. They do not provide a longest-match mode.

#### Regex Match Expression

Regex match expressions use the `=~` operator to search a `StringView` with a
regex constant expression. This is a newer regex-matching form intended to
replace experimental `lexmatch`. The expression returns `Bool`.

```moonbit
input =~ re"abc"
input =~ ((PREFIX + SUFFIX) as whole, before=head, after=tail)
input =~ (re"b", before~, after~)
```

The right-hand side must be a regex constant expression: a regex literal such
as `re"abc"`, a named `const`, or an expression built from constants with `+`
(concatenation), `|` (alternation), and parentheses. Arbitrary runtime values
are not allowed.

Use `as` to bind the matched substring. Use `before` and `after` to bind the
unmatched prefix and suffix as `StringView`; `before~` and `after~` are
shorthand forms that bind variables named `before` and `after`.

This is separate from regex named capture groups. For example, in
`re"(?<id>[0-9]+)"`, the name `id` is part of the regex engine's capture
metadata, not a MoonBit binder. If you need a binder in `=~`, use `as`, such
as `(re"(?<id>[0-9]+)" as digits)`.

Like `is`, binders introduced by `=~` can be used in the same boolean-flow
contexts, such as the right-hand side of `&&` and the true branch of `if`.
Regex matching is search-based by default, so `"zabc!" =~ re"abc"` is `true`.
Use anchors such as `^` and `$` when you need to constrain the match to the
beginning or end of the input.

`=~` also uses first-match semantics. It will not support longest-match
behavior.

```moonbit
test {
  let input = " let_name = 42 "
  if (input =~ (
      (REGEX_IDENT_START + REGEX_IDENT_CONT) as ident,
      before=head,
      after=tail
    )) {
    assert_true(head is " ")
    assert_true(ident is "let_name")
    assert_true(tail is " = 42 ")
  } else {
    fail("expected identifier")
  }

  if ("abc" =~ (re"b", before~, after~)) {
    assert_true(before is "a")
    assert_true(after is "c")
  } else {
    fail("expected middle match")
  }

  let source : StringView = "abc"
  if (source =~ (re"." as ch, after=rest)) {
    assert_eq(ch, 'a')
    assert_true(rest is "bc")
  } else {
    fail("expected leading char")
  }

  assert_true("zabc!" =~ re"abc")
  assert_true(!("zabc!" =~ re"^abc"))
}
```

In the example above, `head`, `ident`, `tail`, `before`, `after`, and `rest`
have type `StringView`. The binder `ch` has type `Char`, because `re"."`
matches exactly one character.

#### Lexmatch

##### WARNING
`lexmatch` and `lexmatch?` are deprecated. Prefer
[regex match expression]() in new code.
This section is kept as reference for existing code.

`lexmatch` matches a `String` against a regex pattern and lets you bind the
pieces of a match. The search-mode pattern is `(before, regex pieces, after)`,
where `before` and `after` are optional bindings for the unmatched prefix and
suffix, separated by commas. The regex pieces in the middle are separated by
whitespace only. The regex itself is written as a sequence of string literals,
so you can split it across lines or insert comments between parts. You can
also bind a matched sub-pattern using `as`, such as `("b*" as b)`.

`lexmatch?` is a boolean check similar to `is`, and it can introduce binders
for use in the same contexts as `is` expressions.

In old code, search-mode `lexmatch` looked like this:

```moonbit
lexmatch text {
  (before, "a" ("b*" as b) "c", after) => ...
  _ => ...
}

if text lexmatch? ("a" ("b*" as b) "c") && b.length() > 0 {
  ...
}
```

In new code, write those search-mode checks with `=~` instead.

`lexmatch` also supports a lexer-style mode: `lexmatch <expr> with longest`,
which picks the longest match among alternatives (for example, `if|[a-z]*`
matches `iff` as `iff` in longest mode, while first-match search mode matches
`if` first). Regex match expressions do not provide this longest-match mode.

Regex literals support `\b` and `\B` as part of the regex syntax, but these
word-boundary assertions are not currently available in `regex match expression` constant contexts. They do work when the regex is used as a
first-class `Regex` value, and this restriction is expected to be relaxed in
the future. Regex literals also do not support `\d`, `\D`, `\s`, `\S`, `\w`,
or `\W`. Use POSIX character classes like `[[:digit:]]` inside character
classes instead.

```moonbit
test {
  let text = "xxabbbcyy"
  if text =~ (re"a" + (re"b*" as b) + re"c", before~, after~) {
    inspect(before, content="xx")
    inspect(b, content="bbb")
    inspect(after, content="yy")
  } else {
    fail("")
  }

  if text =~ (re"a" + (re"b*" as b) + re"c") && b.length() > 0 {
    inspect(b, content="bbb")
  }

  let keyword = "iff"
  lexmatch keyword with longest {
    ("if|[a-z]*" as ident) => inspect(ident, content="iff")
    _ => fail("")
  }
}
```

#### Spread Operator

MoonBit provides a spread operator to expand a sequence of elements when
constructing `Array`, `String`, and `Bytes` using the array literal syntax. To
expand such a sequence, it needs to be prefixed with `..`, and it must have
`iter()` method that yields the corresponding type of element.

For example, we can use the spread operator to construct an array:

```moonbit
test {
  let a1 : Array[Int] = [1, 2, 3]
  let a2 : FixedArray[Int] = [4, 5, 6]
  let a3 : @list.List[Int] = @list.from_array([7, 8, 9])
  let a : Array[Int] = [..a1, ..a2, ..a3, 10]
  debug_inspect(a, content="[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]")
}
```

Similarly, we can use the spread operator to construct a string:

```moonbit
test {
  let s1 : String = "Hello"
  let s2 : StringView = "World".view()
  let s3 : Array[Char] = [..s1, ' ', ..s2, '!']
  let s : String = [..s1, ' ', ..s2, '!', ..s3]
  inspect(s, content="Hello World!Hello World!")
}
```

The last example shows how the spread operator can be used to construct a bytes
sequence.

```moonbit
test {
  let b1 : Bytes = b"hello"
  let b2 : BytesView = b1[1:4]
  let b : Bytes = [..b1, ..b2, 10]
  inspect(
    b,
    content=(
      #|b"helloell\x0a"
    ),
  )
}
```

#### TODO syntax

The `todo` syntax (`...`) is a special construct used to mark sections of code that are not yet implemented or are placeholders for future functionality. For example:

```moonbit
fn todo_in_func() -> Int {
  ...
}
```

<!-- path: language/methods.md -->
## Method and Trait

### Method system

MoonBit supports methods in a different way from traditional object-oriented languages. A method in MoonBit is just a toplevel function associated with a type constructor.
To define a method, prepend `SelfTypeName::` in front of the function name, such as `fn SelfTypeName::method_name(...)`, and the method belongs to `SelfTypeName`.
Within the signature of the method declaration, you can use `Self` to refer to `SelfTypeName`.

##### WARNING
Currently, there is a shorthand syntax for defining methods.
When the name of the first parameter is `self`, a function declaration will be considered a method for the type of `self`.
This syntax may be deprecated in the future, and we do not recommend using it in new code.

```moonbit
fn method_name(self : SelfType) -> Unit { ... }
```

```moonbit
enum List[X] {
  Nil
  Cons(X, List[X])
}

///|
fn[X] List::length(xs : List[X]) -> Int {
  ...
}
```

To call a method, you can either invoke using qualified syntax `T::method_name(..)`, or using dot syntax where the first argument is the type of `T`:

```moonbit
let l : List[Int] = Nil
println(l.length())
println(List::length(l))
```

When the first parameter of a method is also the type it belongs to, methods can be called using dot syntax `x.method(...)`. MoonBit automatically finds the correct method based on the type of `x`, there is no need to write the type name and even the package name of the method:

```moonbit
pub(all) enum List[X] {
  Nil
  Cons(X, List[X])
}

pub fn[X] List::concat(list : List[List[X]]) -> List[X] {
  ...
}
```

```moonbit
// assume `xs` is a list of lists, all the following two lines are equivalent
let _ = xs.concat()
let _ = @list.List::concat(xs)
```

Unlike regular functions, methods defined using the `TypeName::method_name` syntax support overloading:
different types can define methods of the same name, because each method lives in a different name space:

```moonbit
struct T1 {
  x1 : Int
}

fn T1::default() -> T1 {
  { x1: 0 }
}

struct T2 {
  x2 : Int
}

fn T2::default() -> T2 {
  { x2: 0 }
}

test {
  let t1 = T1::default()
  let t2 = T2::default()

}
```

#### Local method

To ensure single source of truth in method resolution and avoid ambiguity,
[methods can only be defined in the same package as its type](packages.md#trait-implementations).
However, there is one exception to this rule: MoonBit allows defining *private* methods for foreign types locally.
These local methods can override methods from the type's own package (MoonBit will emit a warning in this case),
and provide extension/complementary to upstream API:

```moonbit
fn Int::my_int_method(self : Int) -> Int {
  self * self + self
}

test {
  assert_eq((6).my_int_method(), 42)
}
```

#### Alias methods as functions

MoonBit allows calling methods with alternative names via alias.

The method alias will create a method with the corresponding name.
You can also choose to create a function with the corresponding name.
The visibility can also be controlled.

```moonbit
##alias(m)
##alias(n, visibility="priv")
##as_free_fn(m)
##as_free_fn(n, visibility="pub")
fn List::f() -> Bool {
  true
}
test {
  assert_eq(List::f(), List::m())
  assert_eq(List::m(), m())
}
```

### Operator Overloading

MoonBit supports overloading infix operators of builtin operators via several builtin traits. For example:

```moonbit
struct T {
  x : Int
}

impl Add for T with add(self : T, other : T) -> T {
  { x: self.x + other.x }
}

test {
  let a = { x: 0 }
  let b = { x: 2 }
  assert_eq((a + b).x, 2)
}
```

Other operators are overloaded via methods with annotations, for example `_[_]` and `_[_]=_`:

```moonbit
struct Coord {
  mut x : Int
  mut y : Int
}

##alias("_[_]")
fn Coord::get(coord : Self, key : String) -> Int {
  match key {
    "x" => coord.x
    "y" => coord.y
  }
}

##alias("_[_]=_")
fn Coord::set(coord : Self, key : String, val : Int) -> Unit {
  match key {
    "x" => coord.x = val
    "y" => coord.y = val
  }
}
```

```moonbit
fn main {
  let c = { x: 1, y: 2 }
  println("{x: \{c.x}, y: \{c.y}}")
  println(c["y"])
  c["x"] = 23
  println("{x: \{c.x}, y: \{c.y}}")
  println(c["x"])
}
```

```default
{x: 1, y: 2}
2
{x: 23, y: 2}
23
```

Currently, the following operators can be overloaded:

| Operator Name         | overloading mechanism   |
|-----------------------|-------------------------|
| `+`                   | trait `Add`             |
| `-`                   | trait `Sub`             |
| `*`                   | trait `Mul`             |
| `/`                   | trait `Div`             |
| `%`                   | trait `Mod`             |
| `==`                  | trait `Eq`              |
| `<<`                  | trait `Shl`             |
| `>>`                  | trait `Shr`             |
| `-` (unary)           | trait `Neg`             |
| `_[_]` (get item)     | method + alias `_[_]`   |
| `_[_] = _` (set item) | method + alias `_[_]=_` |
| `_[_:_]` (view)       | method + alias `_[_:_]` |
| `&`                   | trait `BitAnd`          |
| `|`                   | trait `BitOr`           |
| `^`                   | trait `BitXOr`          |

When overloading `_[_]`/`_[_] = _`/`_[_:_]`, the method must have a correcnt signature:

- `_[_]` should have signature `(Self, Index) -> Result`, used as `let result = self[index]`
- `_[_]=_` should have signature `(Self, Index, Value) -> Unit`, used as `self[index] = value`
- `_[_:_]` should have signature `(Self, start? : Index, end? : Index) -> Result`, used as `let result = self[start:end]`

By implementing `_[_:_]` method, you can create a view for a user-defined type. Here is an example:

```moonbit
struct DataView(String)

struct Data {}

##alias("_[_:_]")
fn Data::as_view(_self : Data, start? : Int = 0, end? : Int) -> DataView {
  "[\{start}, \{end.unwrap_or(100)})"
}

test {
  let data = Data::{  }
  inspect(data[:].0, content="[0, 100)")
  inspect(data[2:].0, content="[2, 100)")
  inspect(data[:5].0, content="[0, 5)")
  inspect(data[2:5].0, content="[2, 5)")
}
```

### Trait system

MoonBit provides a trait system for overloading/ad-hoc polymorphism. Traits declare a list of operations, which must be supplied when a type wants to implement the trait. Traits can be declared as follows:

```moonbit
pub(open) trait I {
  method_(Int) -> Int
  method_with_label(Int, label~ : Int) -> Int
  //! method_with_label(Int, label?: Int) -> Int
}
```

In the body of a trait definition, a special type `Self` is used to refer to the type that implements the trait.

#### Extending traits

A trait can depend on other traits, for example:

```moonbit
pub(open) trait Position {
  pos(Self) -> (Int, Int)
}

pub(open) trait Draw {
  draw(Self, Int, Int) -> Unit
}

pub(open) trait Object: Position + Draw {}
```

#### Implementing traits

To implement a trait, a type must explicitly provide all the methods required by the trait
using the syntax `impl Trait for Type with method_name(...) { ... }`. For example:

```moonbit
pub(open) trait MyShow {
  to_string(Self) -> String
}

struct MyType {}

pub impl MyShow for MyType with to_string(self) {
  ...
}

struct MyContainer[_] {}

/// trait implementation with type parameters.
/// `[X : Show]` means the type parameter `X` must implement `Show`,
/// this will be covered later.
pub impl[X : MyShow] MyShow for MyContainer[X] with to_string(self) {
  ...
}
```

Type annotation can be omitted for trait `impl`: MoonBit will automatically infer the type based on the signature of `Trait::method` and the self type.

The author of the trait can also define **default implementations** for some methods in the trait, for example:

```moonbit
pub(open) trait J {
  f(Self) -> Unit
  f_twice(Self) -> Unit = _
}

impl J with f_twice(self) {
  self.f()
  self.f()
}
```

Note that in addition to the actual default implementation `impl J with f_twice`,
a mark `= _` is also required in the declaration of `f_twice` in `J`.
The `= _` mark is an indicator that this method has default implementation,
it enhances readability by allowing readers to know which methods have default implementation at first glance.

Implementers of trait `J` don't have to provide an implementation for `f_twice`: to implement `J`, only `f` is necessary.
They can always override the default implementation with an explicit `impl J for Type with f_twice`, if desired, though.

```moonbit
impl J for Int with f(self) {
  println(self)
}

impl J for String with f(self) {
  println(self)
}

impl J for String with f_twice(self) {
  println(self)
  println(self)
}

```

To implement the sub trait, one will have to implement the super traits,
and the methods defined in the sub trait. For example:

```moonbit
impl Position for Point with pos(self) {
  (self.x, self.y)
}

impl Draw for Point with draw(self, x, y) {
  ()
}

impl Object for Point

pub fn[O : Object] draw_object(obj : O) -> Unit {
  let (x, y) = obj.pos()
  obj.draw(x, y)
}

test {
  let p = Point::{ x: 1, y: 2 }
  draw_object(p)
}
```

For traits where all methods have default implementation,
it is still necessary to explicitly implement them,
in order to support features such as [abstract trait](packages.md#traits).
For this purpose, MoonBit provides the syntax `impl Trait for Type` (i.e. without the method part).
`impl Trait for Type` ensures that `Type` implements `Trait`,
MoonBit will automatically check if every method in `Trait` has corresponding implementation (custom or default).

In addition to handling traits where every methods has a default implementation,
the `impl Trait for Type` can also serve as documentation, or a TODO mark before filling actual implementation.

##### WARNING
Currently, an empty trait without any method is implemented automatically.

#### Using traits

When declaring a generic function, the type parameters can be annotated with the traits they should implement, allowing the definition of constrained generic functions. For example:

```moonbit
fn[X : Eq] contains(xs : Array[X], elem : X) -> Bool {
  for x in xs {
    if x == elem {
      return true
    }
  } nobreak {
    false
  }
}
```

Without the `Eq` requirement, the expression `x == elem` in `contains` will result in a type error. Now, the function `contains` can be called with any type that implements `Eq`, for example:

```moonbit
struct Point {
  x : Int
  y : Int
}

impl Eq for Point with equal(p1, p2) {
  p1.x == p2.x && p1.y == p2.y
}

test {
  assert_false(contains([1, 2, 3], 4))
  assert_true(contains([1.5, 2.25, 3.375], 2.25))
  assert_false(contains([{ x: 2, y: 3 }], { x: 4, y: 9 }))
}
```

##### Invoke trait methods directly

Methods of a trait can be called directly via `Trait::method`. MoonBit will infer the type of `Self` and check if `Self` indeed implements `Trait`, for example:

```moonbit
test {
  assert_eq(Show::to_string(42), "42")
  assert_eq(Compare::compare(1.0, 2.5), -1)
}
```

Trait implementations can also be invoked via dot syntax, with the following restrictions:

1. if a regular method is present, the regular method is always favored when using dot syntax
2. only trait implementations that are located in the package of the self type can be invoked via dot syntax
   - if there are multiple trait methods (from different traits) with the same name available, an ambiguity error is reported

The above rules ensures that MoonBit's dot syntax enjoys good property while being flexible.
For example, adding a new dependency never break existing code with dot syntax due to ambiguity.
These rules also make name resolution of MoonBit extremely simple:
the method called via dot syntax must always come from current package or the package of the type!

Here's an example of calling trait `impl` with dot syntax:

```moonbit
struct MyCustomType {}

pub impl Show for MyCustomType with output(self, logger) {
  ...
}

fn f() -> Unit {
  let x = MyCustomType::{  }
  let _ = x.to_string()
}
```

### Trait objects

MoonBit supports runtime polymorphism via trait objects.
If `t` is of type `T`, which implements trait `I`,
one can pack the methods of `T` that implements `I`, together with `t`,
into a runtime object via `t as &I`.
When the expected type of an expression is known to be a trait object type, `as &I` can be omitted.
Trait object erases the concrete type of a value,
so objects created from different concrete types can be put in the same data structure and handled uniformly:

```moonbit
pub(open) trait Animal {
  speak(Self) -> String
}

struct Duck(String)

fn Duck::make(name : String) -> Duck {
  Duck(name)
}

impl Animal for Duck with speak(self) {
  "\{self.0}: quack!"
}

struct Fox(String)

fn Fox::make(name : String) -> Fox {
  Fox(name)
}

impl Animal for Fox with speak(_self) {
  "What does the fox say?"
}

test {
  let duck1 = Duck::make("duck1")
  let duck2 = Duck::make("duck2")
  let fox1 = Fox::make("fox1")
  let animals : Array[&Animal] = [duck1, duck2, fox1]
  debug_inspect(
    animals.map(fn(animal) { animal.speak() }),
    content=(
      #|["duck1: quack!", "duck2: quack!", "What does the fox say?"]
    ),
  )
}
```

Not all traits can be used to create objects.
"object-safe" traits' methods must satisfy the following conditions:

- `Self` must be the first parameter of a method
- There must be only one occurrence of `Self` in the type of the method (i.e. the first parameter)

Users can define new methods for trait objects, just like defining new methods for structs and enums:

```moonbit
pub(open) trait Logger {
  write_string(Self, String) -> Unit
}

pub(open) trait CanLog {
  log(Self, &Logger) -> Unit
}

fn[Obj : CanLog] &Logger::write_object(self : &Logger, obj : Obj) -> Unit {
  obj.log(self)
}

/// use the new method to simplify code
pub impl[A : CanLog, B : CanLog] CanLog for (A, B) with log(self, logger) {
  let (a, b) = self
  logger
  ..write_string("(")
  ..write_object(a)
  ..write_string(", ")
  ..write_object(b)
  .write_string(")")
}
```

### Builtin traits

MoonBit provides the following useful builtin traits:

<!-- MANUAL CHECK https://github.com/moonbitlang/core/blob/80cf250d22a5d5eff4a2a1b9a6720026f2fe8e38/builtin/traits.mbt -->
```moonbit
trait Eq {
  op_equal(Self, Self) -> Bool
}

trait Compare : Eq {
  // `0` for equal, `-1` for smaller, `1` for greater
  compare(Self, Self) -> Int
}

trait Hash {
  hash_combine(Self, Hasher) -> Unit // to be implemented
  hash(Self) -> Int // has default implementation
}

trait Show {
  output(Self, Logger) -> Unit // to be implemented
  to_string(Self) -> String // has default implementation
}

trait Default {
  default() -> Self
}
```

#### Deriving builtin traits

MoonBit can automatically derive implementations for some builtin traits:

```moonbit
struct T {
  a : Int
  b : Int
} derive(Eq, Compare, Debug, Default)

test {
  let t1 = T::default()
  let t2 = T::{ a: 1, b: 1 }
  debug_inspect(t1, content="{ a: 0, b: 0 }")
  debug_inspect(t2, content="{ a: 1, b: 1 }")
  assert_false(t1 == t2)
  assert_true(t1 < t2)
}
```

See [Deriving](derive.md) for more information about deriving traits.

<!-- path: language/derive.md -->
## Deriving traits

MoonBit supports deriving a number of builtin traits automatically from the type definition.

To derive a trait `T`, it is required that all fields used in the type implements `T`.
For example, deriving `Show` for a struct `struct A { x: T1; y: T2 }` requires both `T1: Show` and `T2: Show`

### Eq and Compare

`derive(Eq)` and `derive(Compare)` will generate the corresponding method for testing equality and comparison.
Fields are compared in the same order as their definitions.
For enums, the order between cases ascends in the order of definition.

```moonbit
struct DeriveEqCompare {
  x : Int
  y : Int
} derive(Eq, Compare)

test "derive eq_compare struct" {
  let p1 = DeriveEqCompare::{ x: 1, y: 2 }
  let p2 = DeriveEqCompare::{ x: 2, y: 1 }
  let p3 = DeriveEqCompare::{ x: 1, y: 2 }
  let p4 = DeriveEqCompare::{ x: 1, y: 3 }

  // Eq
  assert_eq(p1 == p2, false)
  assert_eq(p1 == p3, true)
  assert_eq(p1 == p4, false)
  assert_eq(p1 != p2, true)
  assert_eq(p1 != p3, false)
  assert_eq(p1 != p4, true)

  // Compare
  assert_eq(p1 < p2, true)
  assert_eq(p1 < p3, false)
  assert_eq(p1 < p4, true)
  assert_eq(p1 > p2, false)
  assert_eq(p1 > p3, false)
  assert_eq(p1 > p4, false)
  assert_eq(p1 <= p2, true)
  assert_eq(p1 >= p2, false)
}
```

```moonbit
enum DeriveEqCompareEnum {
  Case1(Int)
  Case2(label~ : String)
  Case3
} derive(Eq, Compare)

test "derive eq_compare enum" {
  let p1 = DeriveEqCompareEnum::Case1(42)
  let p2 = DeriveEqCompareEnum::Case1(43)
  let p3 = DeriveEqCompareEnum::Case1(42)
  let p4 = DeriveEqCompareEnum::Case2(label="hello")
  let p5 = DeriveEqCompareEnum::Case2(label="world")
  let p6 = DeriveEqCompareEnum::Case2(label="hello")
  let p7 = DeriveEqCompareEnum::Case3

  // Eq
  assert_eq(p1 == p2, false)
  assert_eq(p1 == p3, true)
  assert_eq(p1 == p4, false)
  assert_eq(p1 != p2, true)
  assert_eq(p1 != p3, false)
  assert_eq(p1 != p4, true)

  // Compare
  assert_eq(p1 < p2, true) // 42 < 43
  assert_eq(p1 < p3, false)
  assert_eq(p1 < p4, true) // Case1 < Case2
  assert_eq(p4 < p5, true)
  assert_eq(p4 < p6, false)
  assert_eq(p4 < p7, true) // Case2 < Case3
}
```

### Debug

`derive(Debug)` will generate a structural debugging implementation for the type.
It is useful with `debug_inspect` in tests and `@debug.to_string` when formatting diagnostic messages.

```moonbit
struct DebugPoint {
  x : Int
  y : Int
} derive(Debug)

test "derive debug struct" {
  let point = DebugPoint::{ x: 1, y: 2 }
  debug_inspect(point, content="{ x: 1, y: 2 }")
}
```

Enums can derive `Debug` as well:

```moonbit
enum DebugShape {
  Circle(radius~ : Int)
  Rect(width~ : Int, height~ : Int)
} derive(Debug)

test "derive debug enum" {
  let shape = DebugShape::Rect(width=3, height=4)
  debug_inspect(shape, content="Rect(width=3, height=4)")
}
```

### Default

`derive(Default)` will generate a method that returns the default value of the type.

For structs, the default value is the struct with all fields set as their default value.

```moonbit
struct DeriveDefault {
  x : Int
  y : String?
} derive(Default, Eq)

test "derive default struct" {
  let p = DeriveDefault::default()
  assert_true(p == DeriveDefault::{ x: 0, y: None })
}
```

For enums, the default value is the only case that has no parameters.

```moonbit
enum DeriveDefaultEnum {
  Case1(Int)
  Case2(label~ : String)
  Case3
} derive(Default, Eq)

test "derive default enum" {
  assert_true(DeriveDefaultEnum::default() == DeriveDefaultEnum::Case3)
}
```

Enums that has no cases or more than one cases without parameters cannot derive `Default`.

<!-- MANUAL CHECK  should not compile -->
```moonbit
enum CannotDerive1 {
    Case1(String)
    Case2(Int)
} derive(Default) // cannot find a constant constructor as default

enum CannotDerive2 {
    Case1
    Case2
} derive(Default) // Case1 and Case2 are both candidates as default constructor
```

### Hash

`derive(Hash)` will generate a hash implementation for the type.
This will allow the type to be used in places that expects a `Hash` implementation,
for example `HashMap`s and `HashSet`s.

```moonbit
struct DeriveHash {
  x : Int
  y : String?
} derive(Hash, Eq)

test "derive hash struct" {
  let hs = @hashset.HashSet([])
  hs.add(DeriveHash::{ x: 123, y: None })
  hs.add(DeriveHash::{ x: 123, y: None })
  @test.assert_eq(hs.length(), 1)
  hs.add(DeriveHash::{ x: 123, y: Some("456") })
  @test.assert_eq(hs.length(), 2)
}
```

### Arbitrary

`derive(Arbitrary)` will generate random values of the given type.

### FromJson and ToJson

`derive(FromJson)` and `derive(ToJson)` automatically derives round-trippable method implementations
used for serializing the type to and from JSON.
The implementation is mainly for debugging and storing the types in a human-readable format.

```moonbit
struct JsonTest1 {
  x : Int
  y : Int
} derive(FromJson, ToJson, Eq)

enum JsonTest2 {
  A(x~ : Int)
  B(x~ : Int, y~ : Int)
} derive(FromJson(style="legacy"), ToJson(style="legacy"), Eq)

test "json basic" {
  let input = JsonTest1::{ x: 123, y: 456 }
  let expected : Json = { "x": 123, "y": 456 }
  @test.assert_eq(input.to_json(), expected)
  assert_true(@json.from_json(expected) == input)
  let input = JsonTest2::A(x=123)
  let expected : Json = { "$tag": "A", "x": 123 }
  @test.assert_eq(input.to_json(), expected)
  assert_true(@json.from_json(expected) == input)
}
```

Both derive directives accept a number of arguments to configure the exact behavior of serialization and deserialization.

##### WARNING
The actual behavior of JSON serialization arguments is unstable.

##### WARNING
JSON derivation arguments are only for coarse-grained control of the derived format.
If you need to precisely control how the types are laid out,
consider **directly implementing the two traits instead**.

We have recently deprecated a large number of advanced layout tweaking arguments.
For such usage and future usage of them, please manually implement the traits.
The arguments include: `repr`, `case_repr`, `default`, `rename_all`, etc.

```moonbit
struct JsonTest3 {
  x : Int
  y : Int
} derive (
  FromJson(fields(x(rename="renamedX"))),
  ToJson(fields(x(rename="renamedX"))),
  Eq,
)

enum JsonTest4 {
  A(x~ : Int)
  B(x~ : Int, y~ : Int)
} derive(FromJson, ToJson, Eq)

test "json args" {
  let input = JsonTest3::{ x: 123, y: 456 }
  let expected : Json = { "renamedX": 123, "y": 456 }
  @test.assert_eq(input.to_json(), expected)
  assert_true(@json.from_json(expected) == input)
  let input = JsonTest4::A(x=123)
  let expected : Json = ["A", { "x": 123 }]
  @test.assert_eq(input.to_json(), expected)
  assert_true(@json.from_json(expected) == input)
}
```

#### Enum styles

There are currently two styles of enum serialization: `legacy` and `flat`,
which the user must select one using the `style` argument.
Considering the following enum definition:

```moonbit
enum E {
  One
  Uniform(Int)
  Axes(x~: Int, y~: Int)
}
```

With `derive(ToJson(style="legacy"))`, the enum is formatted into:

```default
E::One              => { "$tag": "One" }
E::Uniform(2)       => { "$tag": "Uniform", "0": 2 }
E::Axes(x=-1, y=1)  => { "$tag": "Axes", "x": -1, "y": 1 }
```

With `derive(ToJson(style="flat"))`, the enum is formatted into:

```default
E::One              => "One"
E::Uniform(2)       => [ "Uniform", 2 ]
E::Axes(x=-1, y=1)  => [ "Axes", -1, 1 ]
```

##### Deriving `Option`

A notable exception is the builtin type `Option[T]`.
Ideally, it would be interpreted as `T | undefined`, but the issue is that it would be
impossible to distinguish `Some(None)` and `None` for `Option[Option[T]]`.

As a result, it interpreted as `T | undefined` iff it is a direct field
of a struct, and `[T] | null` otherwise:

```moonbit
struct A {
  x : Int?
  y : Int??
  z : (Int?, Int??)
} derive(ToJson)

test {
  json_inspect({ x: None, y: None, z: (None, None) }, content={
    "z": [null, null],
  })
  json_inspect({ x: Some(1), y: Some(None), z: (Some(1), Some(None)) }, content={
    "x": 1,
    "y": null,
    "z": [[1], [null]],
  })
  json_inspect({ x: Some(1), y: Some(Some(1)), z: (Some(1), Some(Some(1))) }, content={
    "x": 1,
    "y": [1],
    "z": [[1], [[1]]],
  })
}
```

#### Container arguments

- `rename_fields` and `rename_cases` (enum only)
  batch renames fields (for enums and structs) and enum cases to the given format.
  Available parameters are:
  - `lowercase`
  - `UPPERCASE`
  - `camelCase`
  - `PascalCase`
  - `snake_case`
  - `SCREAMING_SNAKE_CASE`
  - `kebab-case`
  - `SCREAMING-KEBAB-CASE`

  Example: `rename_fields = "PascalCase"`
  for a field named `my_long_field_name`
  results in `MyLongFieldName`.

  Renaming assumes the name of fields in `snake_case`
  and the name of structs/enum cases in `PascalCase`.
- `cases(...)` (enum only) controls the layout of enum cases.

  #### WARNING
  This might be replaced with case attributes in the future.

  For example, for an enum
  ```moonbit
  enum E {
    A(...)
    B(...)
  }
  ```

  you are able to control each case using `cases(A(...), B(...))`.

  See [Case arguments]() below for details.
- `fields(...)` (struct only) controls the layout of struct fields.

  #### WARNING
  This might be replaced with field attributes in the future.

  For example, for a struct
  ```moonbit
  struct S {
    x: Int
    y: Int
  }
  ```

  you are able to control each field using `fields(x(...), y(...))`

  See [Field arguments]() below for details.

#### Case arguments

- `rename = "..."` renames this specific case,
  overriding existing container-wide rename directive if any.
- `fields(...)` controls the layout of the payload of this case.
  Note that renaming positional fields are not possible currently.

  See [Field arguments]() below for details.

#### Field arguments

- `rename = "..."` renames this specific field,
  overriding existing container-wide rename directives if any.

<!-- path: language/error-handling.md -->
## Error handling

Error handling has always been at core of our language design. In the following
we'll be explaining how error handling is done in MoonBit. We assume you have
some prior knowledge of MoonBit, if not, please checkout
[A tour of MoonBit](../tutorial/tour.md).

### Error Types

In MoonBit, all the error values can be represented by the `Error` type, a
generalized error type.

However, an `Error` cannot be constructed directly. A concrete error type must
be defined, in the following forms:

```moonbit
suberror E1 { E1(Int) } // error type E1 has one constructor E1 with an Int payload

suberror E2 // error type E2 has one constructor E2 with no payload

suberror E3 { // error type E3 has three constructors like a normal enum type
  A
  B(Int, x~ : String)
  C(mut x~ : String, Char, y~ : Bool)
}
```

##### WARNING
The older `suberror A B` syntax is deprecated. Use `suberror A { A(B) }` instead.

The error types can be promoted to the `Error` type automatically, and pattern
matched back:

```moonbit
suberror CustomError { CustomError(UInt) }

test {
  let e : Error = CustomError(42)
  guard e is CustomError(m)
  assert_eq(m, 42)
}
```

Since the type `Error` can include multiple error types, pattern matching on the
`Error` type must use the wildcard `_` to match all error types. For example,

```moonbit
fn f(e : Error) -> Unit {
  match e {
    E2 => println("E2")
    A => println("A")
    B(i, x~) => println("B(\{i}, \{x})")
    _ => println("unknown error")
  }
}
```

The `Error` is meant to be used where no concrete error type is needed, or a
catch-all for all kinds of sub-errors is needed.

#### Failure

A builtin error type is `Failure`.

There's a handly `fail` function, which is merely a constructor with a
pre-defined output template for showing both the error and the source location.
In practice, `fail` is always preferred over `Failure`.

<!-- MANUAL CHECK -->
```moonbit
##callsite(autofill(loc))
pub fn[T] fail(msg : String, loc~ : SourceLoc) -> T raise Failure {
  raise Failure("FAILED: \{loc} \{msg}")
}
```

### Throwing Errors

The keyword `raise` is used to interrupt the function execution and return an
error.

The type declaration of a function can use `raise` with an Error type to
indicate that the function might raise an error during an execution. For
example, the following function `div` might return an error of type `DivError`:

```moonbit
suberror DivError { DivError(String) } derive(Debug)

fn div(x : Int, y : Int) -> Int raise DivError {
  if y == 0 {
    raise DivError("division by zero")
  }
  x / y
}
```

The `Error` can be used when the concrete error type is not important. For
convenience, you can omit the error type after the `raise` to indicate that the
`Error` type is used. For example, the following function signatures are
equivalent:

```moonbit
fn f() -> Unit raise {
  ...
}

fn g() -> Unit raise Error {
  let h : () -> Unit raise = fn() raise { fail("fail") }
  ...
}
```

For functions that are generic in the error type, you can use the `Error` bound
to do that. For example,

```moonbit
// Result::unwrap_or_error
fn[T, E : Error] unwrap_or_error(result : Result[T, E]) -> T raise E {
  match result {
    Ok(x) => x
    Err(e) => raise e
  }
}
```

For functions that do not raise an error, you can add `noraise` in the
signature. For example:

```moonbit
fn add(a : Int, b : Int) -> Int noraise {
  a + b
}
```

#### Error Polymorphism

It happens when a higher order function accepts another function as parameter.
The function as parameter may or may not throw error, which in turn affects the
behavior of this function.

A notable example is `map` of `Array`:

```moonbit
fn[T] map(array : Array[T], f : (T) -> T raise) -> Array[T] raise {
  let mut res = []
  for x in array {
    res.push(f(x))
  }
  res
}
```

However, writing so would make the `map` function constantly having the
possibility of throwing errors, which is not the case.

Thus, the error polymorphism is introduced. You may use `raise?` to signify that
an error may or may not be throw.

```moonbit
fn[T] map_with_polymorphism(
  array : Array[T],
  f : (T) -> T raise?
) -> Array[T] raise? {
  let mut res = []
  for x in array {
    res.push(f(x))
  }
  res
}

fn[T] map_without_error(
  array : Array[T],
  f : (T) -> T noraise,
) -> Array[T] noraise {
  map_with_polymorphism(array, f)
}

fn[T] map_with_error(array : Array[T], f : (T) -> T raise) -> Array[T] raise {
  map_with_polymorphism(array, f)
}
```

The signature of the `map_with_polymorphism` will be determined by the actual
parameter.

### Handling Errors

Applying the function normally will rethrow the error directly in case of an
error. For example:

```moonbit
fn div_reraise(x : Int, y : Int) -> Int raise DivError {
  div(x, y) // Rethrow the error if `div` raised an error
}
```

However, you may want to handle the errors.

#### Try ... Catch

You can use `try` and `catch` to catch and handle errors, for example:

```moonbit
fn main {
  try div(42, 0) catch {
    DivError(s) => println(s)
  } noraise {
    v => println(v)
  }
}
```

```default
division by zero
```

Here, `try` is used to call a function that might throw an error, and `catch` is
used to match and handle the caught error. If no error is caught, the catch
block will not be executed and the `noraise` block will be executed instead.

The `noraise` block can be omitted if no action is needed when no error is
caught. For example:

```moonbit
try { println(div(42, 0)) } catch {
  _ => println("Error")
}
```

When the body of `try` is a simple expression, the curly braces, and even the
`try` keyword can be omitted. For example:

```moonbit
let a = div(42, 0) catch { _ => 0 }
println(a)
```

#### Transforming to Result

You can also catch the potential error and transform into a first-class value of
the [`Result`](fundamentals.md#option-and-result) type, by using
`try?` before an expression that may throw error:

```moonbit
test {
  let res = try? (div(6, 0) * div(6, 3))
  match res {
    Err(DivError(message)) => @test.assert_eq(message, "division by zero")
    Ok(_) => fail("expected division to fail")
  }
}
```

#### Panic on Errors

You can also panic directly when an unexpected error occurs:

```moonbit
fn remainder(a : Int, b : Int) -> Int raise DivError {
  if b == 0 {
    raise DivError("division by zero")
  }
  let div = try! div(a, b)
  a - b * div
}
```

#### Error Inference

Within a `try` block, several different kinds of errors can be raised. When that
happens, the compiler will use the type `Error` as the common error type.
Accordingly, the handler must use the wildcard `_` to make sure all errors are
caught, and `e => raise e` to reraise the other errors. For example,

```moonbit
fn f1() -> Unit raise E1 {
  ...
}

fn f2() -> Unit raise E2 {
  ...
}

try {
  f1()
  f2()
} catch {
  E1(_) => ...
  E2 => ...
  e => raise e
}
```

<!-- path: language/packages.md -->
## Managing Projects with Packages

When developing projects at large scale, the project usually needs to be divided into smaller modular unit that depends on each other.
More often, it involves using other people's work: most noticeably is the [core](https://github.com/moonbitlang/core), the standard library of MoonBit.

### Packages and modules

In MoonBit, the most important unit for code organization is a package, which consists of a number of source code files and a single package configuration file (`moon.pkg`, or the legacy `moon.pkg.json` format).
A package can either be a `main` package, consisting a `main` function, or a package that serves as a library, identified by the [`is-main`](../toolchain/moon/package.md#is-main) field.

A project, corresponding to a module, consists of multiple packages and a single `moon.mod.json` configuration file.

A module is identified by the [`name`](../toolchain/moon/module.md#name) field, which usually consists of two parts, separated by `/`: `user-name/project-name`.
A package is identified by the relative path to the source root defined by the [`source`](../toolchain/moon/module.md#source-directory) field. The full identifier would be `user-name/project-name/path-to-pkg`.

When using things from another package, the dependency between modules should first be declared inside the `moon.mod.json` by the [`deps`](../toolchain/moon/module.md#dependency-management) field.
The dependency between packages should then be declared in the package file (`moon.pkg`, or legacy `moon.pkg.json`) by the [`import`](../toolchain/moon/package.md#import) field.
Most core packages follow the same rule: if you use `@json`, `@test`, or other
ordinary core aliases, add the corresponding `moonbitlang/core/...` package to
`import` to avoid `core_package_not_imported` warnings.

<a id="default-alias"></a>

The **default alias** of a package is the last part of the identifier split by `/`.
One can use `@pkg_alias` to access the imported entities, where `pkg_alias` is either the full identifier or the default alias.
A custom alias may also be defined with the [`import`](../toolchain/moon/package.md#import) field.

In `moon.pkg`, a custom alias is written as:

```text
import {
  "moonbit-community/language/packages/pkgA",
  "moonbit-community/language/packages/pkgC" @c,
  "moonbitlang/core/builtin",
}
```

```moonbit
///|
pub fn add1(x : Int) -> Int {
  @moonbitlang/core/builtin.Add::add(0, @c.incr(@pkgA.incr(x)))
}
```

#### Prelude and builtin names

If `@pkg.` is omitted, MoonBit resolves an unqualified name in the current
package and the prelude. A local definition with the same name therefore
shadows the prelude definition.

```moonbit
fn println(msg : String) -> String {
  "log: \{msg}"
}

///|
fn shadowed_println() -> String {
  println("hello")
}

///|
fn builtin_answer() -> Int {
  let answer : Int = 42
  answer
}
```

`prelude` is a special package: it is available by default, and names exposed
through it participate in normal unqualified name resolution without an
explicit `import`.

Compiler builtins are a separate category. Types such as `Int` are built into
the language itself, not imported from any package, so there is no
`@builtin.Int`. The same distinction applies to other compiler-known names such
as `String`, `Bool`, and `Unit`.

#### Internal Packages

You can define internal packages that are only available for certain packages.

Code in `a/b/c/internal/x/y/z` are only available to packages `a/b/c` and `a/b/c/**`.

#### Using

You can use `using` syntax to import symbols defined in another package.

```moonbit
///|
pub using @pkgA {incr, trait Trait, type Type}
```

By having `pub` modifier, it is considered as reexportation.

<a id="access-control"></a>

### Access Control

MoonBit features a comprehensive access control system that governs which parts of your code are accessible from other packages.
This system helps maintain encapsulation, information hiding, and clear API boundaries.
The visibility modifiers apply to functions, variables, types, and traits, allowing fine-grained control over how your code can be used by others.

#### Functions

By default, all function definitions and variable bindings are *invisible* to other packages.
You can use the `pub` modifier before toplevel `let`/`fn` to make them public.

#### Aliases

By default, [function alias](fundamentals.md#function-alias) and
[method alias](methods.md#alias-methods-as-functions) follow the
visibility of the original definition, while
[type alias](fundamentals.md#type-alias), [using]() are *invisible* to other
packages.

You can add the `pub` modifier before the definition or fill in the `visibility`
field within the annotation.

#### Types

There are four different kinds of visibility for types in MoonBit:

- Private type: declared with `priv`, completely invisible to the outside world
- Abstract type: which is the default visibility for types.

  Only the name of an abstract type is visible outside, the internal representation of the
  type is hidden. Making abstract type by default is a design choice to encourage
  encapsulation and information hiding.
- Readonly types, declared with `pub`.

  The internal representation of readonly types are visible outside,
  but users can only read the values of these types from outside, construction and mutation are not allowed.
- Fully public types, declared with `pub(all)`.

  The outside world can freely construct, read values of these types and modify them if possible.

In addition to the visibility of the type itself, the fields of a public `struct` can be annotated with `priv`,
which will hide the field from the outside world completely.
Note that `struct`s with private fields cannot be constructed directly outside,
but you can update the public fields using the functional struct update syntax.

Readonly types is a very useful feature, inspired by [private types](https://ocaml.org/manual/5.3/privatetypes.html) in OCaml.
In short, values of `pub` types can be destructed by pattern matching and the dot syntax, but
cannot be constructed or mutated in other packages.

##### NOTE
There is no restriction within the same package where `pub` types are defined.

<!-- MANUAL CHECK -->
```moonbit
// Package A
pub struct RO {
  field: Int
}
test {
  let r = { field: 4 }       // OK
  let r = { ..r, field: 8 }  // OK
}

// Package B
fn println(r : RO) -> Unit {
  println("{ field: ")
  println(r.field)  // OK
  println(" }")
}
test {
  let r : RO = { field: 4 }  // ERROR: Cannot create values of the public read-only type RO!
  let r = { ..r, field: 8 }  // ERROR: Cannot mutate a public read-only field!
}
```

Access control in MoonBit adheres to the principle that a `pub` type, function, or variable cannot be defined in terms of a private type. This is because the private type may not be accessible everywhere that the `pub` entity is used. MoonBit incorporates sanity checks to prevent the occurrence of use cases that violate this principle.

<!-- MANUAL CHECK -->
```moonbit
pub(all) type T1
pub(all) type T2
priv type T3

pub(all) struct S {
  x: T1  // OK
  y: T2  // OK
  z: T3  // ERROR: public field has private type `T3`!
}

// ERROR: public function has private parameter type `T3`!
pub fn f1(_x: T3) -> T1 { ... }
// ERROR: public function has private return type `T3`!
pub fn f2(_x: T1) -> T3 { ... }
// OK
pub fn f3(_x: T1) -> T1 { ... }

pub let a: T3 = { ... } // ERROR: public variable has private type `T3`!
```

#### Traits

There are four visibility for traits, just like `struct` and `enum`: private, abstract, readonly and fully public.

- Private traits are declared with `priv trait`, and they are completely invisible from outside.
- Abstract trait is the default visibility. Only the name of the trait is visible from outside, and the methods in the trait are not exposed.
- Readonly traits are declared with `pub trait`, their methods can be invoked from outside, but only the current package can add new implementation for readonly traits.
- Fully public traits are declared with `pub(open) trait`, they are open to new implementations outside current package, and their methods can be freely used.

Abstract and readonly traits are sealed, because only the package defining the trait can implement them.
Implementing a sealed (abstract or readonly) trait outside its package result in compiler error.

##### Trait Implementations

Implementations have independent visibility, just like functions. The type will not be considered having fulfillled the trait outside current package unless the implementation is `pub`.

To make the trait system coherent (i.e. there is a globally unique implementation for every `Type: Trait` pair),
and prevent third-party packages from modifying behavior of existing programs by accident,
MoonBit employs the following restrictions on who can define methods/implement traits for types:

- *only the package that defines a type can define methods for it*. So one cannot define new methods or override old methods for builtin and foreign types.
  - there is an exception to this rule: [local methods](methods.md#local-method). Local methods are always private though, so they do not break coherence properties of MoonBit's type system
- *only the package of the type or the package of the trait can define an implementation*.
  For example, only `@pkg1` and `@pkg2` are allowed to write `impl @pkg1.Trait for @pkg2.Type`.

The second rule above allows one to add new functionality to a foreign type by defining a new trait and implementing it.
This makes MoonBit's trait & method system flexible while enjoying good coherence property.

##### WARNING
Currently, an empty trait is implemented automatically.

Here's an example of abstract trait:

<!-- MANUAL CHECK -->
```moonbit
trait Number {
 op_add(Self, Self) -> Self
 op_sub(Self, Self) -> Self
}

fn[N : Number] add(x : N, y: N) -> N {
  Number::op_add(x, y)
}

fn[N : Number] sub(x : N, y: N) -> N {
  Number::op_sub(x, y)
}

impl Number for Int with op_add(x, y) { x + y }
impl Number for Int with op_sub(x, y) { x - y }

impl Number for Double with op_add(x, y) { x + y }
impl Number for Double with op_sub(x, y) { x - y }
```

From outside this package, users can only see the following:

```moonbit
trait Number

fn[N : Number] op_add(x : N, y : N) -> N
fn[N : Number] op_sub(x : N, y : N) -> N

impl Number for Int
impl Number for Double
```

The author of `Number` can make use of the fact that only `Int` and `Double` can ever implement `Number`,
because new implementations are not allowed outside.

### Virtual Packages

##### WARNING
Virtual package is an experimental feature. There may be bugs and undefined behaviors.

You can define virtual packages, which serves as an interface. They can be replaced by specific implementations at build time. Currently virtual packages can only contain plain functions.

Virtual packages can be useful when swapping different implementations while keeping the code untouched.

#### Defining a virtual package

You need to declare it to be a virtual package and define its interface in a MoonBit interface file.

Within `moon.pkg`, you will need to add field [`virtual`](../toolchain/moon/package.md#declarations) :

```text
options(
  "virtual": { "has-default": true },
)
```

The `has-default` indicates whether the virtual package has a default implementation.

Within the package, you will need to add an interface file `pkg.mbti`:

```moonbit
package "moonbit-community/language/packages/virtual"

fn log(String) -> Unit
```

The first line of the interface file need to be `package "full-package-name"`. Then comes the declarations.
The `pub` keyword for [access control]() and the function parameter names should be omitted.

#### Implementing a virtual package

A virtual package can have a default implementation. By defining [`virtual.has-default`](../toolchain/moon/package.md#declarations) as `true`, you can implement the code as usual within the same package.

```moonbit
///|
pub fn log(s : String) -> Unit {
  println(s)
}
```

A virtual package can also be implemented by a third party. By defining [`implements`](../toolchain/moon/package.md#implementations) as the target package's full name, the compiler can warn you about the missing implementations or the mismatched implementations.

```text
options(
  implement: "moonbit-community/language/packages/virtual",
)
```

```moonbit
///|
pub fn log(string : String) -> Unit {
  ignore(string)
}
```

#### Using a virtual package

To use a virtual package, it's the same as other packages: define [`import`](../toolchain/moon/package.md#import) field in the package where you want to use it.

#### Overriding a virtual package

If a virtual package has a default implementation and that is your choice, there's no extra configurations.

Otherwise, you may define the [`overrides`](../toolchain/moon/package.md#overriding-implementations) field by providing an array of implementations that you would like to use.

```text
import {
  "moonbit-community/language/packages/virtual",
}

options(
  "is-main": true,
  overrides: [ "moonbit-community/language/packages/implement" ],
)
```

You should reference the virtual package when using the entities.

```moonbit
///|
fn main {
  @virtual.log("Hello")
}
```

<!-- path: language/tests.md -->
## Writing Tests

Tests are important for improving quality and maintainability of a program. They verify the behavior of a program and also serves as a specification to avoid regressions over time.

MoonBit comes with test support to make the writing easier and simpler.

### Test Blocks

MoonBit provides the test code block for writing inline test cases. For example:

```moonbit
test "test_name" {
  assert_eq(1 + 1, 2)
  assert_eq(2 + 2, 4)
  debug_inspect([1, 2, 3], content="[1, 2, 3]")
}
```

A test code block is essentially a function that returns a `Unit` but may throws an [`Error`](error-handling.md#error-types), or `Unit!Error` as one would see in its signature at the position of return type. It is called during the execution of `moon test` and outputs a test report through the build system. The `assert_eq` function is from the standard library; if the assertion fails, it prints an error message and terminates the test. The string `"test_name"` is used to identify the test case and is optional.

If a test name starts with `"panic"`, it indicates that the expected behavior of the test is to trigger a panic, and the test will only pass if the panic is triggered. For example:

```moonbit
test "panic_test" {
  let _ : Int = Option::None.unwrap()
}
```

### Snapshot Tests

Writing tests can be tedious when specifying the expected values. Thus, MoonBit provides three kinds of snapshot tests.
All of which can be inserted or updated automatically using `moon test --update`.

#### Snapshotting `Show`

We can use `inspect(x, content="x")` to inspect anything that implements `Show` trait.
As we mentioned before, `Show` is a builtin trait that can be derived, providing `to_string` that will print the content of the data structures.
The labelled argument `content` can be omitted as `moon test --update` will insert it for you:

```moonbit
struct X {
  x : Int
} derive(Debug)

test "show snapshot test" {
  debug_inspect({ x: 10 }, content="{ x: 10 }")
}
```

#### Snapshotting `JSON`

The problem with the derived `Show` trait is that it does not perform pretty printing, resulting in extremely long output.

The solution is to use `@json.inspect(x, content=x)`. The benefit is that the resulting content is a JSON structure, which can be more readable after being formatted.

```moonbit
enum Rec {
  End
  Really_long_name_that_is_difficult_to_read(Rec)
} derive(Debug, ToJson)

test "json snapshot test" {
  let r = Really_long_name_that_is_difficult_to_read(
    Really_long_name_that_is_difficult_to_read(
      Really_long_name_that_is_difficult_to_read(End),
    ),
  )
  debug_inspect(
    r,
    content="Really_long_name_that_is_difficult_to_read(Really_long_name_that_is_difficult_to_read(Really_long_name_that_is_difficult_to_read(End)))",
  )
  json_inspect(r, content=[
    "Really_long_name_that_is_difficult_to_read",
    [
      "Really_long_name_that_is_difficult_to_read",
      ["Really_long_name_that_is_difficult_to_read", "End"],
    ],
  ])
}
```

One can also implement a custom `ToJson` to keep only the essential information.

#### Snapshotting Anything

Still, sometimes we want to not only record one data structure but the output of a whole process.

A full snapshot test can be used to record anything using `@test.T::write` and `@test.T::writeln`:

```moonbit
test "record anything" (t : @test.Test) {
  t.write("Hello, world!")
  t.writeln(" And hello, MoonBit!")
  t.snapshot(filename="record_anything.txt")
}
```

This will create a file under `__snapshot__` of that package with the given filename:

```default
Hello, world! And hello, MoonBit!
```

This can also be used for applications to test the generated output, whether it were creating an image, a video or some custom data.

Please note that `@test.T::snapshot` should be used at the end of a test block, as it always raises exception.

### BlackBox Tests and WhiteBox Tests

When developing libraries, it is important to verify if the user can use it correctly. For example, one may forget to make a type or a function public. That's why MoonBit provides BlackBox tests, allowing developers to have a grasp of how others are feeling.

- A test that has access to all the members in a package is called a WhiteBox tests as we can see everything. Such tests can be defined inline or defined in a file whose name ends with `_wbtest.mbt`.
- A test that has access only to the public members in a package is called a BlackBox tests. Such tests need to be defined in a file whose name ends with `_test.mbt`.

The WhiteBox test files (`_wbtest.mbt`) imports the packages defined in the `import` and `wbtest-import` sections of the package configuration (`moon.pkg`, or legacy `moon.pkg.json`).

The BlackBox test files (`_test.mbt`) imports the current package and the packages defined in the `import` and `test-import` sections of the package configuration (`moon.pkg`, or legacy `moon.pkg.json`).

<!-- path: language/benchmarks.md -->
## Writing Benchmarks

Benchmarks are a way to measure the performance of your code. They can be used to compare different implementations or to track performance changes over time.

### Benchmarking with Test Blocks

The most simple way to benchmark a function is to use a test block with a
`@bench.T` argument. It has a method `@bench.T::bench` that takes a function of type
`() -> Unit` and run it with a suitable number of iterations.
The measurements and statistical analysis will be conducted and passed to `moon`,
where they will be displayed in the console output.

```moonbit
fn fib(n : Int) -> Int {
  if n < 2 {
    return n
  }
  return fib(n - 1) + fib(n - 2)
}

test (b : @bench.T) {
  b.bench(fn() { b.keep(fib(20)) })
}
```

The output is as follows:

```default
time (mean ± σ)         range (min … max) 
  21.67 µs ±   0.54 µs    21.28 µs …  23.14 µs  in 10 ×   4619 runs
```

The function is executed `10 × 4619` times.
The second number is automatically detected by benchmark utilities, which increase the number of iterations until the measurement time is long enough for accurate timing.
The first number can be adjusted by passing a named parameter `count` to the `@bench.T::bench` argument.

```moonbit
test (b : @bench.T) {
  b.bench(fn() { b.keep(fib(20)) }, count=20)
}
```

`@bench.T::keep` is an important auxiliary function that prevents your calculation from being optimized away and skipped entirely.
If you are benchmarking a pure function, make sure to use this function to avoid potential optimizations.
However, there is still a possibility that the compiler might pre-calculate and replace the calculation with a constant.

### Batch Benchmarking

A common scenario of benchmarking is to compare two or more implementations of the same function.
In this case, you may want to bench them in a batch within a block for easy comparison.
The `name` parameter of the `@bench.T::bench` method can be used to identify the benchmark.

```moonbit
fn fast_fib(n : Int) -> Int {
  if n < 2 {
    return n
  } else {
    let mut a = 0
    let mut b = 1
    for i = 2; i <= n; i = i + 1 {
      let t = a + b
      a = b
      b = t
    }
    b
  }
}

test (b : @bench.T) {
  b.bench(name="naive_fib", fn() { b.keep(fib(20)) })
  b.bench(name="fast_fib", fn() { b.keep(fast_fib(20)) })
}
```

Now you can evaluate which one is faster by looking at the output:

```default
name      time (mean ± σ)         range (min … max) 
naive_fib   21.01 µs ±   0.21 µs    20.76 µs …  21.32 µs  in 10 ×   4632 runs
fast_fib     0.02 µs ±   0.00 µs     0.02 µs …   0.02 µs  in 10 × 100000 runs
```

### Raw Benchmark Statistics

Sometimes users may want to obtain raw benchmark statistics for further analysis.
There is a function `@bench.single_bench` that returns an abstract `Summary` type, which can be serialized into JSON format. The stability of the `Summary` type is not guaranteed to be stable.

In this case, users must ensure that the calculation is not optimized away.
There is no `keep` function available as a standalone function; it is a method of `@bench.T`.

```moonbit
fn collect_bench() -> Unit {
  let mut saved = 0
  let summary : @bench.Summary = @bench.single_bench(name="fib", fn() {
    saved = fib(20)
  })
  println(saved)
  println(summary.to_json().stringify(escape_slash=true, indent=4))
}
```

The output may look like this:

```json
6765
{
    "name": "fib",
    "sum": 217.22039973878972,
    "min": 21.62009230518067,
    "max": 21.87286402916848,
    "mean": 21.72203997387897,
    "median": 21.70412048323901,
    "var": 0.007197724461032505,
    "std_dev": 0.08483940394081341,
    "std_dev_pct": 0.39056830777787843,
    "median_abs_dev": 0.08189815918589166,
    "median_abs_dev_pct": 0.3773392211360855,
    "quartiles": [
        21.669052078798433,
        21.70412048323901,
        21.76141434479756
    ],
    "iqr": 0.09236226599912811,
    "batch_size": 4594,
    "runs": 10
}
```

Time units are in microseconds.

<!-- path: language/docs.md -->
## Comments and Documentation

### Comments

Use `//` for ordinary comments inside code:

```moonbit
// Explain why this branch exists.
let retries = 3
```

You will also often see `///|` at the start of top-level blocks. It is an
empty doc-comment line used to split top-level items explicitly. This matters
for documentation tooling today, and it also preserves clear top-level block
boundaries for future caching and other tooling purposes. In practice, `///|`
is useful in ordinary MoonBit code as well as in documentation sources.

### Doc Comments

Doc comments use `///` on each line immediately before a top-level item such as
`fn`, `let`, `enum`, `struct`, or `type`. Doc comments are written in
Markdown.

```moonbit
/// Return a new array with reversed elements.
fn[T] reverse(xs : Array[T]) -> Array[T] {
  ...
}
```

Markdown code blocks inside doc comments marked with `mbt check` are treated as
document tests. `moon check` and `moon test` will automatically check and run
these tests, so that examples in doc comments are always up-to-date.
Wrap the snippet in `test { .. }` when you want a test block:

```moonbit
/// Increment an integer by one,
///
/// Example:
/// ```mbt check
/// test {
///   inspect(incr(41), content="42")
/// }
/// ```
pub fn incr(x : Int) -> Int {
  x + 1
}
```

If you want to prevent a code snippet from being treated as a document test,
mark it with a language id other than `mbt check` on the markdown code block:

```moonbit
/// `c_incr(x)` is the same as the following C code:
/// ```c
/// x++
/// ```
pub fn c_incr(x : Ref[Int]) -> Int {
  let old = x.val
  x.val += 1
  old
}
```

Currently, document tests are always [blackbox tests](tests.md#blackbox-tests-and-whitebox-tests).
So private definitions cannot have document test.

### Literate `.mbt.md` Files

MoonBit also supports literate Markdown files ending in `.mbt.md`. These files
can live inside a package as checked documentation, or they can be used as
standalone single-file inputs to `moon check` and `moon test`.

For a standalone file, run:

```bash
moon check README.mbt.md
moon test README.mbt.md
```

Inside a project, keep using the package-level `moon check` and `moon test`
commands instead.

The code fence language controls how each block is handled:

- `mbt`: MoonBit code that is compiled, but does not create a test entry.
- `mbt check`: MoonBit document-test code. Use `test { .. }` or `async test`
  inside the block when you want assertions.
- `mbt nocheck`: Show MoonBit code without compiling or testing it.
- `moonbit`: Ordinary displayed code block for documentation; it is not
  compiled or tested.

For example:

```markdown
```mbt nocheck
///|
fn helper() -> Int {
  42
}
```

```mbt check
///|
test "forty two" {
  inspect(40 + 2, content="42")
}
```

```mbt nocheck
///|
fn native_only() -> Unit {
  ...
}
```
```

Standalone `.mbt.md` files can also declare front matter to specify imports or
the target backend:

```markdown
---
moonbit:
  import:
    - path: moonbitlang/core/ref
      alias: ref
  backend:
    native
---

```mbt check
fn answer() -> Int {
  let cell : @ref.Ref[Int] = { val: 41 }
  cell.val + 1
}

///|
test "answer" {
  inspect(answer(), content="42")
}
```
```

Use `moonbit.import` when you want to name the packages the file can import
directly. Use `moonbit.deps` when you only want to declare module dependencies
and let Moon synthesize the imports automatically.

<!-- path: language/attributes.md -->
## Attribute

Attributes are annotations placed before structures in source code. They take the form `#attribute(...)`.
An attribute occupies the entire line, and newlines are not allowed within it.
Attributes do not normally affect the meaning of programs. Unused attributes will be reported as warnings.

The syntax of attributes is defined as follows:

```text
attribute ::= '#' attribute-name
            | '#' attribute-name '(' attribute-arguments ')'

attribute-name ::= LIDENT | LIDENT '.' LIDENT

attribute-arguments ::= attribute-argument (',' attribute-argument )*

attribute-argument ::= expr | LIDENT '=' expr

expr ::= LIDENT | UIDENT | STRING | 'true' | 'false'
       | LIDENT '.' LIDENT
       | LIDENT '(' attribute-arguments ')'
       | LIDENT '.' LIDENT '(' attribute-arguments ')'
```

Attributes have two categories: the built-in attributes and user-defined attributes. For example:

```default
##deprecated("message")
##custom.attribute(key="value", flag=true)
```

The first attribute is a built-in attribute; it does not have a namespace prefix in the attribute name. Built-in attributes are recognized by the MoonBit compiler and have specific meanings.

The second attribute is a user-defined attribute; it has a namespace prefix `custom.` in the attribute name. User-defined attributes are ignored by the compiler, but can be used by external tools via parsing the source code.

##### NOTE
MoonBit is designed not to support runtime reflection. It's easy to abuse, making it impossible for toolchains (e.g., the compiler) to catch errors at compile time, which makes code harder to maintain. It also negatively impacts performance optimization.

We prefer to use compile-time code generation, keeping the benefits of static typing and performance (should also be used judiciously to avoid unnecessary complexity).

### Deprecated Attribute

The `#deprecated` attribute is used to mark an API as deprecated. MoonBit emits
a warning when the deprecated API is used, and if the API is listed in completion,
it will be shown with a strikethrough style. For example:

```moonbit
##deprecated
pub fn foo() -> Unit {
  ...
}

##deprecated("Use Bar2 instead")
pub(all) enum Bar {
  Ctor1
  Ctor2
}
```

The `#deprecated` attribute can be used in the following contexts:

- Top-level value declarations (including `fn`, `let`, and `const`)
- Top-level type declarations (including `type`, `struct`, and `enum`)
- Trait method declarations
- Trait default implementations

Common forms include:

- `#deprecated`

  Marks the item as deprecated with a default warning message.
- `#deprecated("Use new_function instead")`

  Marks the item as deprecated with a custom warning message. Every time the deprecated API is used, the provided message will be displayed as a warning.
- `#deprecated("Use new_function instead", skip_current_package=true)`

  Marks the item as deprecated with a custom warning message, but skips emitting warnings when the deprecated API is used within the same package.
- `#deprecated(skip_current_package=true)`

  Marks the item as deprecated with a default warning message, but skips emitting warnings within the same package. When both a message and `skip_current_package` are present, either argument order is accepted.

### Alert Attribute

The `#alert` attribute attaches a category and message to an API. When code uses
the API, MoonBit emits an alert warning.

```moonbit
##alert(unsafe, "This function is unsafe.")
fn[A] alert_unsafe_get(arr : Array[A], index : Int) -> A {
  arr[index]
}
```

The first argument is the alert category, and the second argument is the message
shown to users. The warning can be configured through warning names such as
`alert` and `alert_unsafe`.

For more detail, see [alert warning](../toolchain/moon/package.md#alert-warning).

### Alias Attribute

The `alias` attribute is used to overload operators related to indexing, or to create an alias name for a top-level function or variable. It has two forms:

- `#alias("op")`: where `op` is one of the following strings representing the indexing operators:
  - `_[_]`: for the indexing operator
  - `_[_]=_`: for the indexing assignment operator
  - `_[_:_]`: for the as view operator
- `#alias(id)`: where `id` is a identifier representing the alias name.

Both forms allowed additional arguments:

- `visibility="modifier"`

  A labeled argument, changes the visibility of the alias. The `modifier` can be `pub` or `priv`. If not specified, the alias will have the same visibility as the original function or variable.
- `deprecated` or `deprecated="message"`

  Marks the alias as deprecated. If a message is provided, it will be displayed as a warning when the alias is used.

To graceful migration from old API to new API, you can rename the old API directly, and create an alias with the old name, mark it as deprecated. For
example:

```moonbit
##alias(old_name, deprecated)
fn new_name() -> Unit {
  ()
}
```

### `label_migration` Attribute

The `#label_migration` attribute is used to help you safely evolve your API
by warning users during the transition period.

It has three following forms:

- `#label_migration(id, fill=true, msg="message")`

  The `fill` argument is used when you want to refactor an optional parameter.
  You can use `fill=true` when you want to eventually make an optional
  parameter required. You can use `fill=false` when you want to eventually
  remove an optional parameter.

  The `msg` argument is an string that provides additional information about the migration.
  ```moonbit
  #label_migration(x, fill=true)
  #label_migration(y, fill=false)
  fn label_migration_fill(x? : Int = 0, y? : Int = 1) -> Int {
    x + y
  }
  ```
- `#label_migration(id, allow_positional=true, msg="message")`

  The `allow_positional` argument is used when you want a labelled parameter to be
  used without its label being provided. When the parameter is used positionally
  (without a label), the compiler reports a warning. This is useful when you want to change a positional parameter
  to a labelled parameter without breaking the downstream code.

  The `msg` argument is an string that provides additional information about the migration.
  ```moonbit
  #label_migration(x, allow_positional=true)
  fn label_migration_allow_positional(x~ : Int) -> Int {
    x
  }
  ```
- `#label_migration(id, alias=new_id, msg="message")`

  The alias argument allows you to provide an alternative name to a labelled
  parameter. This is useful when renaming a parameter to maintain backward
  compatibility. If a warning message is provided, the compiler warns when
  using the alias; otherwise, the alias can be used without warnings.

  The `msg` argument is an string that provides additional information about the migration.
  ```moonbit
  #label_migration(x, alias=xx)
  #label_migration(x, alias=y, msg="warning")
  fn label_migration_alias(x~ : Int) -> Int {
    x
  }
  ```

### Visibility Attribute

##### NOTE
This topic does not cover access control. To learn more about `pub`, `pub(all)` and `priv`, see [Access Control](packages.md#id1).

The `#visibility` attribute is similar to the `#deprecated` attribute, but it is used to hint that a type will change its visibility in the future.
For outside usages, if the usage will be invalidated by the visibility change in future, a warning will be emitted.

```moonbit
// in @util package
##visibility(change_to="readonly", "Point will be readonly in the future.")
pub(all) struct Point {
  x : Int
  y : Int
}

##visibility(change_to="abstract", "Use new_text and new_binary instead.")
pub(all) enum Resource {
  Text(String)
  Binary(Bytes)
}

pub fn new_text(str : String) -> Resource {
  ...
}

pub fn new_binary(bytes : Bytes) -> Resource {
  ...
}

// in another package
fn main {
  let p = Point::{ x: 1, y: 2 } // warning
  let { x, y } = p // ok
  println(p.x) // ok
  match Resource::Text("") { // warning
    Text(s) => ... // waning
    Binary(b) => ... // warning
  }
}

```

The `#visibility` attribute takes a required `change_to` argument and an
optional `message` argument.

- The `change_to` argument is a string that indicates the new visibility of the type. It can be either `"abstract"` or `"readonly"`.

  | `change_to`   | Invalidated Usages                                                                                                     |
  |---------------|------------------------------------------------------------------------------------------------------------------------|
  | `"readonly"`  | Creating an instance of the type or mutating the fields of the instance.                                               |
  | `"abstract"`  | Creating an instance of the type, mutating the fields of the instance, pattern matching, or accessing fields by label. |
- The optional `message` argument is a string that provides additional information about the visibility change.

### Internal Attribute

The `#internal` attribute is used to mark a function, type, or trait as internal.
Any usage of the internal function or type in other modules will emit an alert warning.

```moonbit
##internal(unsafe, "This is an unsafe function")
fn[A] internal_unsafe_get(arr : Array[A], index : Int) -> A {
  arr[index]
}
```

The internal attribute takes a required `category` argument and an optional
`message` argument. `category` is a identifier that indicates the category of
the alert, and `message` is a string that provides additional message for the
alert.

The alert warnings can be turn off by setting the `warn-list` in `moon.pkg`.
For more detail, see [alert warning](../toolchain/moon/package.md#alert-warning).

### Doc Hidden Attribute

The `#doc(hidden)` attribute hides an API from generated documentation.

```moonbit
##doc(hidden)
pub fn hidden_helper() -> Unit {
  ()
}
```

Use it for public declarations that must remain available to code but should not
be shown as part of the documented API surface.

### Warnings Attribute

The `#warnings` attribute is used to configure warning settings for a specific
top-level declaration. It can enable, disable or treat an enabled warning as error
for specific warnings in that declaration.

The argument is a string that specifies the warning list. It can contain multiple
warning names, each prefixed with a sign:

```moonbit
##warnings("-unused_value")
fn warnings_example() -> Unit {
  let x = 42
}
```

The prefixes have the following meanings:

- `+warning_name`: enable the warning
- `-warning_name`: disable the warning
- `@warning_name`: treat a enabled warning as an error

Currently this attribute only works with some specific warnings.

To learn more about warning names, see [warning list](../toolchain/moon/package.md#warnings-list).

### Must Implement One Attribute

The `#must_implement_one` attribute is used on traits to require that each
implementation explicitly defines at least one method, instead of relying only on
default method implementations.

Without arguments, at least one method of the trait must be explicitly
implemented:

```moonbit
##must_implement_one
pub(open) trait RequireAnyMethod {
  f(Self) -> Unit = _
  g(Self) -> Unit = _
}

impl RequireAnyMethod with f(_) {}

impl RequireAnyMethod with g(_) {}

type AnyImpl

impl RequireAnyMethod for AnyImpl with f(_) {}
```

With method names, at least one of the listed methods must be explicitly
implemented:

```moonbit
##must_implement_one(f, g)
pub(open) trait RequireSelectedMethod {
  f(Self) -> Unit = _
  g(Self) -> Unit = _
  h(Self) -> Unit = _
}

impl RequireSelectedMethod with f(_) {}

impl RequireSelectedMethod with g(_) {}

impl RequireSelectedMethod with h(_) {}

type SelectedImpl

impl RequireSelectedMethod for SelectedImpl with g(_) {}
```

Multiple `#must_implement_one` attributes can be used on the same trait to
require explicit implementations from multiple method groups.

### Inline Attribute

The `#inline` attribute is an optimization hint for a function. It asks the
compiler to inline the function when possible:

```moonbit
##inline
fn add_one(x : Int) -> Int {
  x + 1
}
```

Use `#inline(never)` to ask the compiler not to inline a function:

```moonbit
##inline(never)
fn keep_stack_frame(x : Int) -> Int {
  x + 1
}
```

These attributes are hints. They do not change the source-level behavior of the
function.

### External Attribute

The `#external` attribute is used to mark an abstract type as external type.

- For Wasm and Wasm GC backends, it would be interpreted as `externref`.
- For JavaScript backend, it would be interpreted as `any`.
- For native backends, it would be interpreted as `void*`.

```moonbit
##external
type AttrPtr
```

### Borrow and Owned Attribute

The `#borrow` and `#owned` attributes are used on FFI declarations to describe
how reference-counted MoonBit arguments are passed to foreign code. This matters
for boxed MoonBit values such as `Bytes`, `String`, `FixedArray[T]`, and
abstract types, whose lifetimes are managed by reference counting on the C and
Wasm backends.

Use `#borrow(param)` when the foreign function only reads `param` during the
call and does not store or return it. A borrowed parameter remains owned by
MoonBit, so the foreign function does not need to call `moonbit_decref` or
`$moonbit.decref` for it.

Use `#owned(param)` when the foreign function takes ownership of `param`, for
example by storing it and releasing it later. An owned parameter must eventually
be released by the foreign side when it is no longer needed.

```moonbit
##borrow(filename)
extern "C" fn open(filename : Bytes, flags : Int) -> Int = "open"
```

For the full calling-convention rules, see
[FFI lifetime management](ffi.md#the-borrow-and-owned-attribute).

### `as_free_fn` Attribute

The `#as_free_fn` attribute is used to mark a method that it is declared as a free function as well.
It can also change the visibility of the free function, the name of the free function, and provide separate deprecation warning.

```moonbit
##as_free_fn(dec, visibility="pub", deprecated="use `Int::decrement` instead")
##as_free_fn(visibility="pub")
fn Int::decrement(i : Self) -> Self {
  i - 1
}

test {
  let _ = decrement(10)
  let _ = (10).decrement()
}
```

### Callsite Attribute

The `#callsite` attribute is used to mark properties that happen at callsite.

It could be `autofill`, which is to autofill the arguments [SourceLoc and ArgLoc](fundamentals.md#id1)
at callsite.

### Skip Attribute

The `#skip` attribute is used to skip a single test block. It can be written as
`#skip` or with a reason, such as `#skip("blocked by external service")`. The
type checking will still be performed.

### Coverage Skip Attribute

The `#coverage.skip` attribute skips coverage operations within a function.

```moonbit
##coverage.skip
fn platform_specific_helper() -> Unit {
  ()
}
```

Use it for functions that should not affect coverage reports, such as
platform-specific fallback code or code paths that are intentionally excluded
from coverage measurement. For more detail, see
[Skipping coverage](../toolchain/moon/coverage.md#skipping-coverage).

### Configuration attribute

The `#cfg` attribute is used to perform conditional compilation. Examples are:

<!-- MANUAL CHECK -->
```moonbit
##cfg(true)
fn cfg_true() -> Unit {
  ()
}

##cfg(false)
fn cfg_false() -> Unit {
  ()
}

##cfg(target="wasm")
fn cfg_wasm() -> Unit {
  ()
}

##cfg(not(target="wasm"))
fn cfg_not_wasm() -> Unit {
  ()
}

##cfg(all(target="wasm", true))
fn cfg_all() -> Unit {
  ()
}

##cfg(any(target="wasm", target="native"))
fn cfg_any() -> Unit {
  ()
}
```

### Module attribute

The `module` attribute is used to declare the module dependency for JavaScript backend.

In `cjs` format, it is interpreted as `require`, and in `esm` format, it is interpreted as `import`.

<!-- MANUAL CHECK -->
```moonbit
##module("math-utils")
pub extern "js" fn add_from_module(x : Int, y : Int) -> Int = "add"
```

<!-- path: language/ffi.md -->
## Foreign Function Interface (FFI)

What we've introduced is about describing pure computation. In reality, you'll need
to interact with the real world. However, the "world" is different for each backend (C, JS, Wasm, WasmGC)
and is sometimes based on runtime ([Wasmtime](https://wasmtime.dev/), Deno, Browser, etc.).

### Backends

MoonBit currently have five backends:

- Wasm
- Wasm GC
- JavaScript
- C
- LLVM (experimental)

#### Wasm

By Wasm we refer to WebAssembly with some post-MVP proposals including:

- bulk-memory-operations
- multi-value
- reference-types

For better compatibility, the `init` function will be compiled as [`start` function](https://webassembly.github.io/spec/core/syntax/modules.html#start-function), and the `main` function will be exported as `_start`.

##### NOTE
For Wasm backends, all functions interacting with outside world relies on the host. For example, the `println` for Wasm and Wasm GC backend relies on importing a function `spectest.print_char` that prints a UTF-16 code unit for each call. The `env` package in standard library and some packages in `moonbitlang/x` relies on specific host function defined for MoonBit runtime. Avoid using them if you want to make the generated Wasm portable.

#### Wasm GC

By Wasm GC we refer to WebAssembly with Garbage Collection proposal, meaning that data structures will be represented with reference types such as `struct` `array` and the linear memory would not be used by default. It also supports other post-MVP proposals including:

- multi-value
- JS string builtins

For better compatibility, the `init` function will be compiled as [`start` function](https://webassembly.github.io/spec/core/syntax/modules.html#start-function), and the `main` function will be exported as `_start`.

##### NOTE
For Wasm backends, all functions interacting with outside world relies on the host. For example, the `println` for Wasm and Wasm GC backend relies on importing a function `spectest.print_char` that prints a UTF-16 code unit for each call. The `env` package in standard library and some packages in `moonbitlang/x` relies on specific host function defined for MoonBit runtime. Avoid using them if you want to make the generated Wasm portable.

#### JavaScript

JavaScript backend will generate a JavaScript file, which can be a CommonJS module, an ES module or an IIFE based on the [configuration](../toolchain/moon/package.md#js-backend-link-options).

#### C

C backend will generate a C file. The MoonBit toolchain will also compile the project and generate an executable based on the [configuration](../toolchain/moon/package.md#native-backend-link-options).

#### LLVM

LLVM backend will generate an object file. The backend is experimental and does not support FFIs.

### Declare Foreign Type

You can declare a foreign type using the `#external` attribute like this:

```moonbit
##external
type ExternalRef
```

#### Wasm & Wasm GC

This will be interpreted as an [`externref`](https://webassembly.github.io/spec/core/syntax/types.html#reference-types).

#### JavaScript

This will be interpreted as a JavaScript value.

#### C

This will be interpreted as `void*`.

### Declare Foreign Function

To interact with the outside world, you can declare foreign functions.

##### NOTE
MoonBit does not support polymorphic foreign functions.

##### IMPORTANT
When declaring functions, you need to make sure that the signature corresponds to the actual foreign function. **Use `-> Unit` when the foreign function returns no value. This corresponds to `void` in C and to a Wasm function with no result.**

#### Wasm & Wasm GC

There are two ways to declare a foreign function: importing a function or writing an inline function.

You can import a function given the module name and the function name from the runtime host:

```moonbit
fn cos(d : Double) -> Double = "math" "cos"
```

Or you can write an inline function using Wasm syntax:

```moonbit
extern "wasm" fn identity(d : Double) -> Double =
  #|(func (param f64) (result f64))
```

##### NOTE
When writing the inline function, do not provide a function name.

#### JavaScript

There are two ways to declare a foreign function: importing a function or writing an inline function.

You can import a function given the module name and the function name, which will be interpreted as `module.function`. For example,

```moonbit
fn cos(d : Double) -> Double = "Math" "cos"
```

would refer to the function `const cos = (d) => Math.cos(d)`

Or you can write an inline function defining a JavaScript lambda:

```moonbit
extern "js" fn cos(d : Double) -> Double =
  #|(d) => Math.cos(d)
```

#### C

You can declare a foreign function by importing a function given the function name:

```moonbit
extern "C" fn put_char(ch : UInt) -> Unit = "function_name"
```

If a package needs to dynamically link with foreign C library, add `cc-link-flags` to `moon.pkg`. It would be passed to C compiler directly.

```moonbit
options(
  "link": {
    "native": {
      "cc-link-flags": "-l<c library>"
    }
  },
)
```

To define wrapper functions, you can add a C stub file to a package, and add the following to the `moon.pkg` of the package:

```moonbit
options(
  "native-stub": [ 
    // list of stub file names
  ],
)
```

You would probably like to `#include "moonbit.h"`, which contains type definitions and handy utilities for MoonBit's C interface. The header is located in `~/.moon/include`, check its content for more details.

#### Types

The table below shows the underlying representation of some MoonBit types:

#### Wasm

| MoonBit type                       | ABI         |
|------------------------------------|-------------|
| `Bool`                             | `i32`       |
| `Int`                              | `i32`       |
| `UInt`                             | `i32`       |
| `Int64`                            | `i64`       |
| `UInt64`                           | `i64`       |
| `Float`                            | `f32`       |
| `Double`                           | `f64`       |
| constant `enum`                    | `i32`       |
| external type (`#external type T`) | `externref` |
| `FuncRef[T]`                       | `funcref`   |

#### Wasm GC

| MoonBit type                       | ABI                                     |
|------------------------------------|-----------------------------------------|
| `Bool`                             | `i32`                                   |
| `Int`                              | `i32`                                   |
| `UInt`                             | `i32`                                   |
| `Int64`                            | `i64`                                   |
| `UInt64`                           | `i64`                                   |
| `Float`                            | `f32`                                   |
| `Double`                           | `f64`                                   |
| constant `enum`                    | `i32`                                   |
| external type (`#external type T`) | `externref`                             |
| `String`                           | `externref` iff JS string builtin is on |
| `FuncRef[T]`                       | `funcref`                               |

#### JavaScript

| MoonBit type                       | ABI          |
|------------------------------------|--------------|
| `Bool`                             | `boolean`    |
| `Int`                              | `number`     |
| `UInt`                             | `number`     |
| `Float`                            | `number`     |
| `Double`                           | `number`     |
| constant `enum`                    | `number`     |
| external type (`#external type T`) | `any`        |
| `String`                           | `string`     |
| `FixedArray[Byte]`/`Bytes`         | `Uint8Array` |
| `FixedArray[T]` / `Array[T]`       | `T[]`        |
| `FuncRef[T]`                       | `Function`   |

##### NOTE
The `FixedArray[T]` for numbers may migrate to `TypedArray` in the future.

#### C

| MoonBit type                       | ABI                                    |
|------------------------------------|----------------------------------------|
| `Bool`                             | `int32_t`                              |
| `Int`                              | `int32_t`                              |
| `UInt`                             | `uint32_t`                             |
| `Int64`                            | `int64_t`                              |
| `UInt64`                           | `uint64_t`                             |
| `Float`                            | `float`                                |
| `Double`                           | `double`                               |
| constant `enum`                    | `int32_t`                              |
| abstract type (`type T`)           | pointer (must be valid MoonBit object) |
| external type (`#external type T`) | `void*`                                |
| `FixedArray[Byte]`/`Bytes`         | `uint8_t*`                             |
| `FixedArray[T]`                    | `T*`                                   |
| `FuncRef[T]`                       | Function pointer                       |

##### NOTE
A foreign function returning `Unit` corresponds to a C function returning `void`. If the return type of `T` in `FuncRef[T]` is `Unit`, then it points to a function that returns `void`.

Types not mentioned above do not have a stable ABI, so your code should not depend on their representations.

#### Callbacks

Sometimes, we want to pass a MoonBit function to the foreign interface as callback. In MoonBit, it is possible to have closures. Per [MDN glossary](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Closures):

> A closure is the combination of a function bundled together (enclosed) with references to its surrounding state (the lexical environment). In other words, a closure gives a function access to its outer scope. In JavaScript, closures are created every time a function is created, at function creation time.

In some cases, we would like to pass the callback function which doesn't capture any local free variables. For this purpose, MoonBit provides a special type `FuncRef[T]`, which represents closed function of type `T`. Values of type `FuncRef[T]` must be closed function of type `T`, otherwise [a type error](error_codes/E4151.md) would occur.

In other cases, a MoonBit function parameter would be represented as a function and an object containing the surrounding state.

#### Wasm & Wasm GC

For Wasm backends, the callbacks will be passed as `externref`, which represents a function of the host. However, it is essential to convert the function together with the captured data to the host's function.

To do so, the Wasm module will import a function under the module `moonbit:ffi` and function name `make_closure`. This function takes a function and an object, where the function's first parameter should be the object, and should return a host's function. That is, the host is responsible for doing the partial application. A possible implementation would be:

```javascript
{ 
  "moonbit:ffi": {
    "make_closure": (funcref, closure) => funcref.bind(null, closure)
  } 
}
```

#### JavaScript

JavaScript supports closure, so there's nothing special to be done here.

#### C

Some C library functions allow supplying extra data in addition to the callback function.
Assume we have the following C library function:

```c
void register_callback(void (*callback)(void*), void *data);
```

we can bind this C function and pass closure to it using the following trick:

```moonbit
extern "C" fn register_callback_ffi(
  call_closure : FuncRef[(() -> Unit) -> Unit],
  closure : () -> Unit
) -> Unit = "register_callback"

fn register_callback(callback : () -> Unit) -> Unit {
  register_callback_ffi(
    fn (f) { f() },
    callback
  )
}
```

Values of type `FuncRef[_]` can be called directly from MoonBit too. This is useful for dynamic loading functions via symbol name or implementing JIT in native backend.

#### Customize integer value of constant enum

In all backends of MoonBit, constant enum (`enum` where all constructors have no payload) are translated to integer.
It is possible to customize the actual integer representation of each constructor,
by adding `= <integer literal>` after constructor declaration:

```moonbit
enum SpecialNumbers {
  Zero = 0
  One
  Two
  Three
  Ten = 10
  FourtyTwo = 42
}
```

If a constructor's integer value is unspecified,
it defaults to one plus the value of the previous constructor (or zero for the first constructor).
This feature is particular useful for binding flags of C libraries.

### Export Functions

For public functions that are neither methods nor polymorphic, they can be exported by configuring the `exports` field in [link configuration](../toolchain/moon/package.md#link-options).

```moonbit
options(
  "link": {
    "<backend>": {
      "exports": [ "add", "fib:test" ]
    }
  }
)
```

The previous example exports functions `add` and `fib`, where `fib` will be exported as `test`.

#### Wasm & Wasm GC

##### NOTE
It is only effective for the package that configures it, i.e. it doesn't affect the downstream packages.

#### JavaScript

##### NOTE
It is only effective for the package that configures it, i.e. it doesn't affect the downstream packages.

There's another `format` option to export as CommonJS module (`cjs`), ES Module (`esm`), or `iife`.

#### C

##### NOTE
It is only effective for the package that configures it, i.e. it doesn't affect the downstream packages.

Renaming the exported function is not supported for now

### Lifetime management

MoonBit is a programming language with garbage collection. Thus when handling external object or passing MoonBit object to host, it is essential to keep in mind the lifetime management. Currently, MoonBit uses reference counting for Wasm backend and C backend. For Wasm GC backend and JavaScript backend, the runtime's GC is reused.

#### Lifetime management of external object

When handling external object/resource in MoonBit, it is important to destroy object or release resource in time to prevent memory/resource leak.

##### NOTE
For C backend only

`moonbit.h` provides an API `moonbit_make_external_object` for handling lifetime of external object/resource using MoonBit's own automatic memory management system:

```c
void *moonbit_make_external_object(
  void (*finalize)(void *self),
  uint32_t payload_size
);
```

`moonbit_make_external_object` will create a new MoonBit object of size `payload_size + sizeof(finalize)`,
the layout of the object is as follows:

```default
| MoonBit object header | ... payload | finalize function |
                        ^
                        |
                        |_
                           pointer returned by `moonbit_make_external_object`
```

so you can treat the object as a pointer to its payload directly. When MoonBit's automatic memory management system finds that an object created by `moonbit_make_external_object` is no longer alive, it will invoke the function `finalize` with the object itself as argument. Now, `finalize` can release external resource/memory held by the object's payload.

##### NOTE
`finalize` **must not** drop the object itself, as this is handled by MoonBit runtime.

On the MoonBit side, objects returned by `moonbit_make_external_object`
should be bind to an *abstract* type, declared using `type T`,
so that MoonBit's memory management system will not ignore the object.

#### Lifetime management of MoonBit object

When passing MoonBit objects to the host through functions, it is essential to take care of the lifetime management of MoonBit itself. As mentioned before, MoonBit's Wasm backend and C backend uses compiler-optimized reference counting to manage lifetime of objects. To avoid memory error or leak, FFI functions must properly maintain the reference count of MoonBit objects.

##### NOTE
For C backend and for Wasm backend only.

##### The calling convention of reference counting

By default, MoonBit uses an owned calling convention for reference counting. That is, callee (the function being invoked) is responsible for dropping its parameters using the `moonbit_decref` / `$moonbit.decref` function. If the parameter is used more than once, the callee should increase the reference count using the `moonbit_incref` / `$moonbit.incref` function. Here are the rules for the necessary operations to perform in different circumstances:

| event                            | operation   |
|----------------------------------|-------------|
| read field/element               | nothing     |
| store into data structure        | `incref`    |
| passed to MoonBit function       | `incref`    |
| passed to other foreign function | nothing     |
| returned                         | nothing     |
| end of scope (not returned)      | `decref`    |

For example, here's a lifetime-correct binding to the standard `open` function for opening a file:

```moonbit
extern "C" fn open(filename : Bytes, flags : Int) -> Int = "open_ffi"
```

```c
int open_ffi(moonbit_bytes_t filename, int flags) {
  int fd = open(filename, flags);
  moonbit_decref(filename);
  return fd;
}
```

##### The managed types

The following types are always unboxed, so there is no need to manage their lifetime:

- builtin number types, such as `Int` and `Double`
- constant `enum` (`enum` where all constructors have no payload)

The following types are always boxed and reference counted:

- `FixedArray[T]`, `Bytes` and `String`
- abstract types (`type T`)

External types (`#external type T`) are also boxed, but they represent external pointers,
so MoonBit will not perform any reference counting operations on them.

The layout of `struct`/`enum` with payload is currently unstable.

##### The borrow and owned attribute

When passing a parameter through the FFI, its ownership may or may not be kept.
The `#borrow` and `#owned` attributes can be used to specify these two conditions.

##### WARNING
We are in the process of migrating the default semantics to `#borrow` instead of `#owned`

The syntax of `#borrow` and `#owned` are as follows:

```moonbit
##borrow(params..)
extern "C" fn c_ffi(..) -> .. = ..
```

where `params` is a subset of the parameters of `c_ffi`.

Parameters of `#borrow` will be passed using borrow based calling convention, that is, the invoked function does not need to `decref` these parameters. If the FFI function only read its parameter locally (i.e. does not return its parameters and does not store them in data structures), you can directly use the `#borrow` attribute. For example, the `open` function mentioned above could be rewritten using `#borrow` as follows:

```moonbit
##borrow(filename)
extern "C" fn open(filename : Bytes, flags : Int) -> Int = "open"
```

There is no need for a stub function anymore: we are binding to the original version of `open` here. With the `#borrow` attribute, this version is still lifetime-correct.

Even if a stub function is still necessary for other reasons, `#borrow` can often simplify the lifetime management. Here are the rules for the necessary operations to perform **on borrow parameters** in different circumstances:

| event                                                   | operation   |
|---------------------------------------------------------|-------------|
| read field / element                                    | nothing     |
| store into data structure                               | `incref`    |
| passed to MoonBit function                              | `incref`    |
| passed to other C function / `#borrow` MoonBit function | nothing     |
| returned                                                | `incref`    |
| end of scope (not returned)                             | nothing     |

The opposite is the `#owned` semantic, where the parameter is stored by the FFI function, and the `decref` needs to be executed manually later.
One use case is registering the callback where the closure would be **owned**.

<!-- path: language/async-experimental.md -->
## Async programming support

MoonBit adopts a coroutine based approach to async programming which is similar to [Kotlin](https://kotlinlang.org/docs/coroutines-overview.html).
Asynchronous programming in MoonBit consists of two parts: compiler support for `async` functions, and the official async runtime `moonbitlang/async`.
Currently, `moonbitlang/async` supports native backend best, has limit support for JavaScript backend, and does not support WebAssembly backend yet.
The API of `moonbitlang/async` is not considered stable, and may change in the future.

<!-- We highly appreciate any feedback or experiment with current design. -->

### Getting started

To use `moonbitlang/async` for asynchronous programming,
you should first run `moon add moonbitlang/async@0.17.0` in your project
to add `moonbitlang/async` as a dependency of your project.
You may also want to set `"preferred-target": "native"` in `moon.mod.json`.
Now, import `moonbitlang/async` and other packages in the `moonbitlang/async` library in `moon.pkg`,
and the asynchronous programming API should be available in your packages.
If you want a workflow-first example, see the [Native CLI Quickstart](../tutorial/cli-quickstart.md).

The list of packages in `moonbitlang/async` and their detailed documentation
can be found on [mooncakes.io](https://mooncakes.io/docs/moonbitlang/async),
and some useful [examples](https://github.com/moonbitlang/async/tree/main/examples) on the GitHub repo of `moonbitlang/async`.
This article will introduce some of the basic concept of `moonbitlang/async` and some of the most important API.

### Async function

Async functions are declared with the `async` keyword.
They implicitly [`raise`](error-handling.md#throwing-errors) errors
and need to declare `noraise` explicitly if otherwise.

```moonbit
async fn my_async_function() -> String {
  let (response, body) = @http.get("https://www.moonbitlang.com")
  guard response.code is (200..<300) else {
    fail("server responded with \{response.code} \{response.reason}")
  }
  body.text()
}
```

Since MoonBit is a statically typed language, the compiler will track its
asyncness, so you can just call async functions like normal functions, the
MoonBit IDE will highlight the async function call with a different style.
If you open the above code snippet with the MoonBit IDE,
you should see the `@http.get` function rendered in italic style with an underline.

Async functions can only be called inside async functions.
Calling `async` function will result in the caller being blocked
and waiting for the callee to return, similar to `await` in many other languages.

MoonBit has first-class support for asynchronous programming.
You can use `async fn main` to declare an asynchronous program entry,
or use `async test` to write test for asynchronous code.
Asynchronous tests are automatically run in parallel by default.
Notice that you must import `moonbitlang/async` in your package to use `async fn main` and `async test`.

### Structured concurrency and task group

If an asynchronous program only call async function directly (i.e. `await`),
then the control flow of the program is linear,
and the program is no different from a normal, synchronous programming.
The fundamental difference between asynchronous program and synchronous program
is the ability to spawn multiple tasks and let them run in parallel.
This ability also brings the new challenge of how to manage tasks robustly,
as the control flow of programs become much more complex due to concurrent tasks.

The `moonbitlang/async` library adapts the *structured concurrency* paradigm
to solve the task management problem and improve robustness of async program.
In `moonbitlang/async`, spawning new task can only be done inside a *task group*,
while task groups can only be created via the `@async.with_task_group` function:

```moonbit
async fn[Result] with_task_group(
  f : async (@async.TaskGroup[Result]) -> Result,
) -> Result
```

The `with_task_group` function creates a new task group,
spawn a new task inside the task group,
and run `f` inside the new task with the group itself as argument.
`f` can then use the group to spawn more new tasks, using various methods such as `spawn_bg`:

```moonbit
/// Spawn a new task in the group and let it run in the background
fn[Result] @async.TaskGroup::spawn_bg(
  group : TaskGroup[Result],
  f : async () -> Unit,
  ...
) -> Unit
```

The magic of structured concurrency lies in the following rule for `with_task_group`:

> `with_task_group` will only return after all tasks inside the group has terminated

`with_task_group` will ensure the above property in all conditions.
Normaly, `with_task_group` will just wait for tasks to complete normally.
If `with_task_group` need to terminate immediately for some reasons, such as fatal error
(by default, `with_task_group` will fail immediately if any of its child task fails,
so that no error can be silently ignored),
it will cancel all child tasks properly, and wait for their cleanup operations to complete.
Altogether, the rule of `with_task_group` ensures that
*orphan tasks* (i.e. unused tasks that are still running because the program forget to cancel it)
can never exist in `moonbitlang/async`.

Here's a simple example of using `with_task_group` to create multiple tasks and let them run in parallel:

```moonbit
async test "with_task_group" {
  let log = []
  @async.with_task_group(group => {
    group.spawn_bg(() => {
      for _ in 0..<3 {
        log.push("task #1 tick")
        @async.sleep(200) // sleep for 200ms
      }
    })
    group.spawn_bg(() => {
      @async.sleep(100)
      for _ in 0..<3 {
        log.push("task #2 tick")
        @async.sleep(200)
      }
    })
  })
  json_inspect(log, content=[
    "task #1 tick", "task #2 tick", "task #1 tick", "task #2 tick", "task #1 tick",
    "task #2 tick",
  ])
}
```

`with_task_group` is a very powerful construct.
It can be used to simulate many async control flow operation.
For example, here's a function that run an async function with a timeout:

```moonbit
async fn with_timeout(timeout : Int, f : async () -> Unit) -> Unit {
  @async.with_task_group(group => {
    group.spawn_bg(no_wait=true, () => {
      @async.sleep(timeout)
      raise Failure::Failure("timeout!")
    })
    f()
  })
}
```

The code itself is very simple, but the semantic of `with_task_group` ensures that this simple function will work properly in every corner case:

- if `f` return successfully before the timeout,
  since the sleep task is spawned with `no_wait=true`, `with_task_group` will not wait for the sleep task.
  To protect its rule, `with_task_group` will cancel the sleep task immediately.
  So `with_timeout(.., f)` will return immediately after `f` returns, without unnecessary delay.
- if `f` fails, the error will propagate to the whole `with_task_group`.
  The sleep task will again get cancelled automatically in this case.
- if `f` is still running when the timeout expires,
  the sleep task will raise a fatal timeout error, aborting the whole group.
  `f` will also get cancelled automatically in this case.

### Cancellation makes asynchronous program modular

In the previous section, "cancellation" has been mentioned multiple times.
Indeed, cancellation is a very important part in asynchronous programming.
In `moonbitlang/async`, every asynchronous operation is cancellable by default, including `with_task_group`.
So when you compose these basic asynchronous operations into bigger program,
no matter how complex your program is, it is automatically cancellable.

When a piece of asynchronous code is cancelled,
the cancellation signal is represented as an error raised at the point where the code previously blocked.
So there is no need to handle cancellation specially:
the cancellation signal will automically propagate through the program,
triggering cleanup operations in `defer` and error handlers.

The ability to cancel arbitrary async code makes async programs highly modular in MoonBit.
The `moonbitlang/async` package provides many useful combinators that perform
timeout limit, automatic retry, etc. for async program,
they all rely on the cancellation mechanism to work properly.
For example, the following program try to make a HTTP request with a timeout,
and allow at most three retry attempts:

```moonbit
async fn make_request() -> String {
  @async.retry(Immediate, max_retry=3, () => {
    @async.with_timeout(1000, () => {
      let (response, body) = @http.get("https://www.moonbitlang.com")
      guard response.code is (200..<300) else {
        fail("the HTTP request is not successful")
      }
      body.text()
    })
  })
}
```

### Interacting with the world

In addition to asynchronous programming primitives,
`moonbitlang/async` also provides an event loop for performing async IO operations,
as well as a rich set of IO operations,
including `http`/`https`, file IO, socket IO and process spawning,
with [decent performance](https://www.moonbitlang.com/blog/moonbit-async#performance-comparison).
You can find a complete list of supported operations and their documentation at [mooncakes.io](https://mooncakes.io/docs/moonbitlang/async),
and simple examples at [the GitHub repo](https://github.com/moonbitlang/async/tree/main/examples).
here's a quick taste of some of the most common features:

```moonbit
async fn download_file(url : String, file_name : String) -> Unit {
  // perform the transfer lazily to save memory
  let (_response, body) = @http.get_stream(url)
  defer body.close()
  let out_file = @fs.create(file_name, permission=0o644)
  defer out_file.close()
  out_file.write_reader(body)
}
```

### JavaScript support

Although `moonbitlang/async` supports native backend best,
it also has basic support for JavaScript backend:

- all IO independent API, such as task group and timeout, are available
- IO related API are not available, because not all JavaScript environment (for example browsers) support them
- the `moonbitlang/async/js_async` provides support for integration with JavaScript promise,
  including waiting for an external JavaScript promise and exporting a MoonBit `async` function as a JavaScript promise.
  This allows interaction with native asynchronous operations of the JavaScript host.

See [the mooncakes.io page for `moonbitlang/async/js_async`](https://mooncakes.io/docs/moonbitlang/async/js_async) fore more details.

<!-- path: language/verification.md -->
## Formal Verification

MoonBit has experimental support for formal verification through `moon prove`.
It lets you write executable MoonBit code, state logical properties about that
code, and discharge the generated proof obligations with the SMT solvers.

At a high level, the workflow looks like this:

1. Write executable code in `.mbt` files.
2. Write predicates, logical helper functions, and lemmas in `.mbtp` files.
3. Enable proof mode in the package.
4. Run `moon prove`.

### Overview Example: Binary Search

The following package gives a compact overview of how verification in MoonBit
fits together. It shows:

- package-level proof enablement
- logic-side predicates in `.mbtp`
- a program-side function in `.mbt`
- preconditions and postconditions
- loop invariants and `proof_yield`
- local `proof_assert` steps
- `proof_reasoning` as a proof-oriented explanation of the loop

First, enable proofs for the package:

```moonbit
options(
  "proof-enabled": true,
)
```

Then define the logic-side specification in `.mbtp`:

```moonbit
predicate in_bounds(xs : FixedArray[Int], i : Int) {
  (0 <= i) && (i < xs.length())
}

predicate sorted(xs : FixedArray[Int]) {
  ∀ i : Int, ∀ j : Int,
    in_bounds(xs, i) && in_bounds(xs, j) && (i <= j) →
      xs[i] <= xs[j]
}

predicate binary_search_ok(xs : FixedArray[Int], key : Int, result : Option[Int]) {
  match result {
    None => ∀ i : Int, in_bounds(xs, i) → xs[i] != key
    Some(result) => in_bounds(xs, result) && xs[result] == key
  }
}
```

Finally, implement the executable function in `.mbt`:

```moonbit
pub fn binary_search(
  xs : FixedArray[Int],
  key : Int,
) -> Int? where {
  proof_require: sorted(xs),
  proof_ensure: result => binary_search_ok(xs, key, result),
} {
  for i = 0, j = xs.length(); i < j; {
    let h = i + (j - i) / 2
    if xs[h] < key {
      proof_assert ∀ idx : Int,
        (0 <= idx) && (idx < h + 1) → xs[idx] < key
      continue h + 1, j
    } else if key < xs[h] {
      proof_assert ∀ idx : Int,
        (h <= idx) && (idx < xs.length()) → key < xs[idx]
      continue i, h
    } else {
      proof_assert xs[h] == key
      break Some(h)
    }
  } nobreak {
    None
  } where {
    proof_invariant: 0 <= i,
    proof_invariant: i <= j,
    proof_invariant: j <= xs.length(),
    proof_invariant: ∀ idx : Int, (0 <= idx) && (idx < i) → xs[idx] < key,
    proof_invariant: ∀ idx : Int, (j <= idx) && (idx < xs.length()) → key < xs[idx],
    proof_yield: res => binary_search_ok(xs, key, res),
    proof_reasoning: (
      #| The loop maintains a candidate window `[i, j)`.
      #| Every index before `i` is known to hold a value `< key`, and every
      #| index from `j` onward is known to hold a value `> key`.
      #|
      #| At midpoint `h` there are three cases:
      #|   - `xs[h] < key`: move the left boundary to `h + 1`
      #|   - `key < xs[h]`: move the right boundary to `h`
      #|   - otherwise, the element at `h` is equal to `key`
      #|
      #| If the loop exits normally, the exclusion invariants cover the whole
      #| array, so no index can contain `key`.
    ),
  }
}
```

This example already shows the main structure of verified MoonBit code:

- `sorted` and `binary_search_ok` are logic-side predicates
- `binary_search` is executable program-side code
- the `where { ... }` block attaches logic-side contracts to the function
- `proof_assert` records local facts that help the prover
- the loop invariants describe the shrinking search window
- `proof_reasoning` records the proof idea in structured prose

The rest of this page explains these pieces in more detail and introduces
additional features such as `#proof_pure`, `proof_decrease`,
`proof_axiomatized`, model-based verification, and the trusted surface.

### Setup

#### Environment Setup

`moon prove` relies on the external Why3 verification toolchain. MoonBit lowers
proof-enabled packages to Why3, and Why3 then dispatches proof obligations to
one or more external solvers.

#### Why3

Why3 is required to run formal verification in MoonBit.

- It is recommended to install Why3 through `opam`.
- The recommended pinned version is `1.7.2`.

Using `opam` makes it easier to keep Why3 aligned with the version expected by
the current MoonBit proof pipeline.

#### External Solvers

At least one external solver must also be installed.

MoonBit currently supports:

- `z3`
- `cvc5`
- `alt-ergo`

Installing more than one solver can improve prover coverage, but a working setup
only requires one of them to be available.

#### Enabling Proofs in a Package

Proof support is enabled per package in `moon.pkg`, as shown in the overview
example above.

Once enabled, the package can contain both ordinary MoonBit source files and
proof-oriented `.mbtp` files. Proof enablement is package-local: if multiple
packages in a module carry proofs, each of those packages must enable it.

### Structure of Verified Code

#### Source Layout

Verification-oriented packages usually split into two layers:

- `.mbt`: executable code, contracts, loop invariants, and local proof steps
- `.mbtp`: predicates, abstract models, invariants, and lemmas

That split keeps runtime code readable while making proof structure explicit.
In the [binary search overview](), the predicates live in `.mbtp` and the
executable search function lives in `.mbt`.

#### Program Side and Logic Side

MoonBit verification has a clear distinction between the program side and the
logic side.

- The program side is executable MoonBit code.
- The logic side is used for specifications and proofs, and may not correspond
  to runtime code at all.

Definitions in `.mbt` files are on the program side. Definitions in `.mbtp`
files are on the logic side.

This distinction is important because program-side definitions and logic-side
definitions are separated:

- program-side definitions are executable and can be called by ordinary MoonBit
  code
- logic-side definitions are used by specifications and proofs
- logic-side definitions in `.mbtp` are not ordinary runtime functions
- program-side code does not call logic-side definitions as part of execution
- logic-side specifications do not in general call arbitrary program-side
  definitions

This separation is the reason verified packages often have both:

- program-side helper functions used by execution
- logic-side predicates or model functions used by contracts

When one definition needs to be visible from both sides, `#proof_pure` is the
mechanism for doing that.

Within a `.mbt` file, contracts and proof annotations are the places where
logic-side reasoning appears inside program code. In particular:

- `proof_require` and `proof_ensure` are logic-side specifications attached to
  program functions
- `proof_assert` states a logical fact that must be proved at that point
- loop annotations such as `proof_invariant`, `proof_yield`, and
  `proof_reasoning` are logic-side statements about executable loops

### Writing Specifications and Proofs

#### Contracts in `.mbt`

MoonBit uses `where { ... }` clauses for function contracts. In the binary
search overview, the function contract appears directly on the program-side
definition:

- `proof_require` states a precondition.
- `proof_ensure` states a postcondition.
- `result` refers to the function result.

Inside executable code, `proof_assert` can be used to record intermediate facts
that help the prover connect the implementation to the specification.

This is often the point where program-side implementation facts are connected to
logic-side predicates and postconditions.

#### Proof-Specific Annotations

Besides `proof_require`, `proof_ensure`, and `proof_assert`, MoonBit also has
proof-specific annotations that control how definitions are treated by the proof
pipeline.

#### `#proof_pure`

`#proof_pure` marks a function as pure from the verifier's point of view. This
is useful for helper functions that compute logical quantities used in
predicates and postconditions, while still being visible on the program side.

```moonbit
##proof_pure
fn height(t : Tree) -> Int {
  match t {
    Empty => 0
    Node(_, _, _, h) => h
  }
}
```

The same helper can then be used in a specification:

```moonbit
predicate cached_height_ok(t : Tree, result : Int) {
  result == height(t)
}
```

The rationale for `#proof_pure` is that some computations naturally belong on
both sides. A helper such as `height` on a tree can be useful in executable
code, but specifications may also want to talk about the same quantity.

Without `#proof_pure`, this typically means:

- writing one program-side definition for execution
- writing a second logic-side definition for specifications
- proving that the two definitions are equivalent before using them

`#proof_pure` avoids that duplication by allowing one side-effect-free MoonBit
definition to be shared across program code and proof-oriented logic.

In larger verified packages, `#proof_pure` is commonly used for helpers such as
structural measures like height, ranking functions, summaries, and other
proof-facing computations that should behave like mathematical functions.

At the moment, `#proof_pure` helpers are best treated as pure specification
helpers rather than fully contracted verified functions. In particular, support
for attaching ordinary verification contracts directly to `#proof_pure`
definitions is still limited.

#### `proof_decrease`

`proof_decrease` supplies a termination measure for recursive definitions.

```moonbit
pub fn countdown(n : Int) -> Int where {
  proof_decrease: n,
  proof_require: 0 <= n,
  proof_ensure: result => 0 <= result,
} {
  if n <= 0 {
    0
  } else {
    countdown(n - 1)
  }
}
```

This annotation is especially important when structural recursion or a numeric
measure is not obvious to the prover from the function body alone.

#### `proof_axiomatized`

`proof_axiomatized` marks a contracted function or lemma as assumed rather than
proved.

This is useful when a definition should be available to later proofs, but its
implementation or proof is intentionally left outside the current verification
boundary.

In practice, `proof_axiomatized` should be used sparingly:

- on a function, it means the verifier assumes the stated contract
- on a lemma, it means the verifier assumes the stated conclusion

For example:

```moonbit
pub fn assumed_nonnegative(x : Int) -> Int where {
  proof_axiomatized: true,
  proof_require: 0 <= x,
  proof_ensure: result => 0 <= result,
} {
  x
}
```

This kind of declaration can be useful as a temporary bridge while a proof is
still being developed, or when the trusted boundary is intentional and explicit.
The important point is that `moon prove` will use the contract as an
assumption, rather than proving it from the function body.

Because these assumptions are not discharged by `moon prove`, they become part
of the trusted surface of the verified package.

#### Predicates and Lemmas in `.mbtp`

Logical properties live in `.mbtp` files. In the [binary search overview](), the
logic side defines:

- `in_bounds` as a basic indexing predicate
- `sorted` as the precondition on the input array
- `binary_search_ok` as the postcondition relating the result to the array and
  the key

For example, predicates in `.mbtp` can define the logical vocabulary used by
contracts:

```moonbit
predicate in_bounds(xs : FixedArray[Int], i : Int) {
  (0 <= i) && (i < xs.length())
}

predicate sorted(xs : FixedArray[Int]) {
  ∀ i : Int, ∀ j : Int,
    in_bounds(xs, i) && in_bounds(xs, j) && (i <= j) →
      xs[i] <= xs[j]
}

predicate binary_search_ok(xs : FixedArray[Int], key : Int, result : Option[Int]) {
  match result {
    None => ∀ i : Int, in_bounds(xs, i) → xs[i] != key
    Some(result) => in_bounds(xs, result) && xs[result] == key
  }
}
```

For larger verified packages, `.mbtp` also holds:

- abstract model functions such as `model(x)`
- representation invariants such as `bridge_inv(x)` or `sparse_array_inv(x)`
- named postconditions such as `deposit_post(...)`
- reusable lemmas

Lemmas are proof-only declarations that capture reusable facts. Small lemmas may
have an empty body when the prover can discharge them directly, while larger
lemmas can use recursive proof structure:

```moonbit
lemma height_nonneg_lemma(t : Tree) where {
  proof_decrease: t,
  proof_require: avl_inv(t),
  proof_ensure: 0 <= height(t),
} {
  match t {
    Empty => ()
    Node(l, _x, r, _h) => {
      height_nonneg_lemma(l)
      height_nonneg_lemma(r)
    }
  }
}
```

In this example, `avl_inv` is a representation invariant for an AVL tree, and
the lemma proves `height(t)` is nonnegative by structural recursion on `t`.

Lemma bodies vary with the amount of proof guidance the solver needs:

- some lemmas have an empty body because the verifier can discharge them directly
- some lemmas use a sequence of `proof_assert` steps to expose intermediate facts
- recursive lemmas can also call other lemmas, including themselves on smaller inputs

#### Loop Invariants

Loops are verified with proof-specific clauses in the loop's `where { ... }`
block. In the [binary search overview](), the loop invariants state that:

- the current search window is always a valid slice `[i, j)`
- every index before `i` contains a value `< key`
- every index from `j` onward contains a value `> key`

The most common loop proof annotations are:

- `proof_invariant`: facts that must hold at every iteration boundary
- `proof_yield`: facts that must hold for values yielded by `break`
- `proof_reasoning`: a proof-oriented explanation of why the loop is correct

In practice, good loop invariants describe the current search window, prefix, or
processed region rather than the entire algorithm all at once.

#### Model-Based Verification

For data structures and stateful systems, the most useful pattern is often:

1. define an abstract model,
2. define a representation invariant,
3. specify each operation against the abstract model.

An AVL tree is a representative example of this style:

```moonbit
fn Tree::model(self : Tree) -> Fset[Int] {
  match self {
    Empty => Fset::empty()
    Node(l, x, r, _) => l.model().union(r.model()).add(x)
  }
}

predicate avl_inv(t : Tree) {
  match t {
    Empty => true
    Node(l, x, r, h) =>
      avl_inv(l) &&
      avl_inv(r) &&
      (∀ y : Int, l.model().mem(y) → y < x) &&
      (∀ y : Int, r.model().mem(y) → x < y) &&
      h == 1 + max2(height(l), height(r)) &&
      -1 <= height(l) - height(r) &&
      height(l) - height(r) <= 1
  }
}
```

Here:

- `model()` maps a concrete tree to its abstract finite-set view
- the quantified conditions inline the ordering constraints over that abstract
  model
- `avl_inv` ties together recursive well-formedness, search-tree ordering, and
  cached-height correctness

This style scales much better than writing large inline boolean formulas in each
contract. Each operation can be specified in terms of the abstract model and
the invariant, and the implementation can then prove local facts until the
named postcondition follows.

#### Recommended Style

- Keep executable logic in `.mbt` and proof logic in `.mbtp`.
- Treat the program side and the logic side as distinct layers with a narrow
  bridge between them.
- Prefer named predicates over large inline formulas.
- Use small, stable invariants and postconditions such as `*_inv` and `*_post`.
- Add `proof_assert` after important construction steps, branches, and loop
  updates when the prover needs help.
- Start with simple algorithmic proofs, then move to model-based verification
  for data structures and protocols.
- Be deliberate about recursive helpers: `#proof_pure` and `proof_decrease`
  often determine whether a proof remains maintainable.

### Running Verification

#### What `moon prove` Checks

Running `moon prove` asks the verifier to prove obligations such as:

- function preconditions imply the function body is safe to execute
- postconditions hold on every return path
- `proof_assert` statements are valid
- loop invariants hold initially and are preserved
- loop termination measures decrease when the loop form supports them
- bounds checks and similar safety properties required by the proof

#### Running the Verifier

From a module root, run:

```bash
moon prove
```

This tries to prove the proof-enabled packages in the current module.

To prove a single package, pass its path:

```bash
moon prove path/to/package
```

In this targeted mode, MoonBit tries to prove only the selected package. Its
dependencies are assumed rather than reproved as part of the same command.

MoonBit lowers the proof-enabled package to Why3 and invokes the configured
provers on the generated verification conditions.

`moon check` and `moon prove` serve different purposes here. `moon check`
validates the package as MoonBit code, while `moon prove` tries to discharge
its proof obligations.

### Trust Model and Limitations

#### Trusted Assumptions

Like any verification system, MoonBit's proof story has a trusted surface: some
facts are assumed by the frontend and backend rather than proved inside user
code.

This trusted surface also includes any user-written item marked
`proof_axiomatized`.

The main trusted assumptions today are:

- verification reasons about mathematical integers rather than machine integers
- any item marked `proof_axiomatized` is assumed rather than proved

For integers, this means proof obligations are checked in an unbounded integer
model. As a result:

- arithmetic proofs do not currently model runtime overflow
- a program can be correct in the proof model and still need explicit range
  discipline in execution
- machine-integer verification is planned, but is not the current default

#### Current Status

Formal verification in MoonBit is still experimental. The surface syntax,
prover integration, and proof ergonomics are actively evolving, so it is best
to treat this as an advanced feature for packages that benefit from strong,
machine-checked guarantees.

#### Preferred Verification Style

MoonBit's current verifier works best with a functional proof style and
model-based specifications.

Imperative features such as local mutation and in-place `FixedArray` updates are
supported, but their verified use is more limited:

- mutable state is expected to remain local
- escaping uses of `FixedArray` are currently not supported
- when both formulations are available, functional-style programs are preferred

### Further Reading

For additional verified programs and reusable proof-oriented libraries, see the
[`moonbit-community/verified`](https://github.com/moonbit-community/verified)
repository.

<!-- path: language/error_codes/index.md -->
## Error Codes Index

##### WARNING
The error codes index is currently WIP.

Many entries currently contain only a brief description of the error code.
You are more than welcomed to expand any of the entries by submitting a PR to
[moonbitlang/moonbit-docs](https://github.com/moonbitlang/moonbit-docs).

This page lists all error codes produced by the MoonBit compiler.

* [E0001](E0001.md)
* [E0002](E0002.md)
* [E0003](E0003.md)
* [E0004](E0004.md)
* [E0005](E0005.md)
* [E0006](E0006.md)
* [E0007](E0007.md)
* [E0008](E0008.md)
* [E0009](E0009.md)
* [E0010](E0010.md)
* [E0011](E0011.md)
* [E0012](E0012.md)
* [E0013](E0013.md)
* [E0014](E0014.md)
* [E0015](E0015.md)
* [E0016](E0016.md)
* [E0017](E0017.md)
* [E0018](E0018.md)
* [E0020](E0020.md)
* [E0021](E0021.md)
* [E0022](E0022.md)
* [E0023](E0023.md)
* [E0024](E0024.md)
* [E0025](E0025.md)
* [E0026](E0026.md)
* [E0027](E0027.md)
* [E0028](E0028.md)
* [E0029](E0029.md)
* [E0030](E0030.md)
* [E0031](E0031.md)
* [E0032](E0032.md)
* [E0033](E0033.md)
* [E0034](E0034.md)
* [E0035](E0035.md)
* [E0036](E0036.md)
* [E0037](E0037.md)
* [E0038](E0038.md)
* [E0039](E0039.md)
* [E0040](E0040.md)
* [E0041](E0041.md)
* [E0042](E0042.md)
* [E0043](E0043.md)
* [E0044](E0044.md)
* [E0045](E0045.md)
* [E0046](E0046.md)
* [E0047](E0047.md)
* [E0049](E0049.md)
* [E0050](E0050.md)
* [E0051](E0051.md)
* [E0052](E0052.md)
* [E0053](E0053.md)
* [E0054](E0054.md)
* [E0055](E0055.md)
* [E0056](E0056.md)
* [E0057](E0057.md)
* [E0058](E0058.md)
* [E0059](E0059.md)
* [E0060](E0060.md)
* [E0061](E0061.md)
* [E0062](E0062.md)
* [E0063](E0063.md)
* [E0064](E0064.md)
* [E0065](E0065.md)
* [E0066](E0066.md)
* [E0067](E0067.md)
* [E0068](E0068.md)
* [E0069](E0069.md)
* [E0070](E0070.md)
* [E0071](E0071.md)
* [E0072](E0072.md)
* [E0073](E0073.md)
* [E0074](E0074.md)
* [E0075](E0075.md)
* [E1000](E1000.md)
* [E1001](E1001.md)
* [E3001](E3001.md)
* [E3002](E3002.md)
* [E3003](E3003.md)
* [E3004](E3004.md)
* [E3005](E3005.md)
* [E3006](E3006.md)
* [E3007](E3007.md)
* [E3008](E3008.md)
* [E3009](E3009.md)
* [E3010](E3010.md)
* [E3011](E3011.md)
* [E3012](E3012.md)
* [E3014](E3014.md)
* [E3016](E3016.md)
* [E3017](E3017.md)
* [E3018](E3018.md)
* [E3019](E3019.md)
* [E3020](E3020.md)
* [E3021](E3021.md)
* [E3022](E3022.md)
* [E3023](E3023.md)
* [E3024](E3024.md)
* [E3100](E3100.md)
* [E3700](E3700.md)
* [E3800](E3800.md)
* [E3801](E3801.md)
* [E4000](E4000.md)
* [E4001](E4001.md)
* [E4002](E4002.md)
* [E4003](E4003.md)
* [E4004](E4004.md)
* [E4005](E4005.md)
* [E4006](E4006.md)
* [E4008](E4008.md)
* [E4010](E4010.md)
* [E4011](E4011.md)
* [E4012](E4012.md)
* [E4013](E4013.md)
* [E4014](E4014.md)
* [E4015](E4015.md)
* [E4017](E4017.md)
* [E4018](E4018.md)
* [E4019](E4019.md)
* [E4020](E4020.md)
* [E4021](E4021.md)
* [E4022](E4022.md)
* [E4023](E4023.md)
* [E4024](E4024.md)
* [E4027](E4027.md)
* [E4028](E4028.md)
* [E4029](E4029.md)
* [E4031](E4031.md)
* [E4032](E4032.md)
* [E4033](E4033.md)
* [E4034](E4034.md)
* [E4036](E4036.md)
* [E4037](E4037.md)
* [E4038](E4038.md)
* [E4039](E4039.md)
* [E4040](E4040.md)
* [E4041](E4041.md)
* [E4042](E4042.md)
* [E4043](E4043.md)
* [E4044](E4044.md)
* [E4046](E4046.md)
* [E4047](E4047.md)
* [E4048](E4048.md)
* [E4049](E4049.md)
* [E4050](E4050.md)
* [E4051](E4051.md)
* [E4052](E4052.md)
* [E4053](E4053.md)
* [E4054](E4054.md)
* [E4055](E4055.md)
* [E4056](E4056.md)
* [E4057](E4057.md)
* [E4059](E4059.md)
* [E4061](E4061.md)
* [E4063](E4063.md)
* [E4064](E4064.md)
* [E4065](E4065.md)
* [E4066](E4066.md)
* [E4067](E4067.md)
* [E4068](E4068.md)
* [E4069](E4069.md)
* [E4070](E4070.md)
* [E4071](E4071.md)
* [E4073](E4073.md)
* [E4074](E4074.md)
* [E4077](E4077.md)
* [E4078](E4078.md)
* [E4080](E4080.md)
* [E4081](E4081.md)
* [E4082](E4082.md)
* [E4084](E4084.md)
* [E4085](E4085.md)
* [E4086](E4086.md)
* [E4087](E4087.md)
* [E4089](E4089.md)
* [E4091](E4091.md)
* [E4092](E4092.md)
* [E4093](E4093.md)
* [E4094](E4094.md)
* [E4095](E4095.md)
* [E4096](E4096.md)
* [E4099](E4099.md)
* [E4100](E4100.md)
* [E4101](E4101.md)
* [E4102](E4102.md)
* [E4104](E4104.md)
* [E4106](E4106.md)
* [E4107](E4107.md)
* [E4108](E4108.md)
* [E4109](E4109.md)
* [E4110](E4110.md)
* [E4111](E4111.md)
* [E4112](E4112.md)
* [E4113](E4113.md)
* [E4114](E4114.md)
* [E4115](E4115.md)
* [E4116](E4116.md)
* [E4117](E4117.md)
* [E4118](E4118.md)
* [E4119](E4119.md)
* [E4120](E4120.md)
* [E4121](E4121.md)
* [E4122](E4122.md)
* [E4124](E4124.md)
* [E4127](E4127.md)
* [E4128](E4128.md)
* [E4130](E4130.md)
* [E4131](E4131.md)
* [E4132](E4132.md)
* [E4133](E4133.md)
* [E4135](E4135.md)
* [E4137](E4137.md)
* [E4138](E4138.md)
* [E4139](E4139.md)
* [E4140](E4140.md)
* [E4141](E4141.md)
* [E4142](E4142.md)
* [E4143](E4143.md)
* [E4144](E4144.md)
* [E4145](E4145.md)
* [E4146](E4146.md)
* [E4147](E4147.md)
* [E4148](E4148.md)
* [E4149](E4149.md)
* [E4151](E4151.md)
* [E4153](E4153.md)
* [E4154](E4154.md)
* [E4155](E4155.md)
* [E4156](E4156.md)
* [E4157](E4157.md)
* [E4158](E4158.md)
* [E4159](E4159.md)
* [E4160](E4160.md)
* [E4161](E4161.md)
* [E4162](E4162.md)
* [E4163](E4163.md)
* [E4164](E4164.md)
* [E4165](E4165.md)
* [E4167](E4167.md)
* [E4168](E4168.md)
* [E4171](E4171.md)
* [E4172](E4172.md)
* [E4173](E4173.md)
* [E4174](E4174.md)
* [E4175](E4175.md)
* [E4176](E4176.md)
* [E4177](E4177.md)
* [E4180](E4180.md)
* [E4181](E4181.md)
* [E4182](E4182.md)
* [E4183](E4183.md)
* [E4184](E4184.md)
* [E4185](E4185.md)
* [E4186](E4186.md)
* [E4187](E4187.md)
* [E4188](E4188.md)
* [E4189](E4189.md)
* [E4190](E4190.md)
* [E4191](E4191.md)
* [E4192](E4192.md)
* [E4193](E4193.md)
* [E4194](E4194.md)
* [E4195](E4195.md)
* [E4196](E4196.md)
* [E4197](E4197.md)
* [E4198](E4198.md)
* [E4199](E4199.md)
* [E4200](E4200.md)
* [E4201](E4201.md)
* [E4202](E4202.md)
* [E4203](E4203.md)
* [E4204](E4204.md)
* [E4205](E4205.md)
* [E4206](E4206.md)
* [E4207](E4207.md)
* [E4208](E4208.md)
* [E4209](E4209.md)
* [E4210](E4210.md)
* [E4211](E4211.md)
* [E4212](E4212.md)
* [E4213](E4213.md)
* [E4214](E4214.md)
* [E4215](E4215.md)
