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

MoonBit はクラウドおよびエッジコンピューティング向けの AI ネイティブなプログラミング言語ツールチェーンです。`wasm`、`wasm-gc`、`js`、`native` を対象とし、1 つのモジュール内で混在バックエンドのプロジェクトを構築するのに適しています。

**ステータス**

MoonBit は現在 beta-preview 段階です。

MoonBit はすでに本番利用が可能です。後方互換性を壊す変更は慎重に評価され、コンパイラのバグも稀であることが期待されます。MoonBit は言語ツールチェーンに深い経験を持つ専任チームによって開発されており、エコシステムは急速に進化しています。

**主な利点**

- 既存のどのソリューションよりも大幅に小さい WASM 出力を生成できます。
- ランタイム性能が大幅に高速です。
- 最先端のコンパイル時性能を備えています。
- シンプルで実用的な、データ指向の言語設計です。

<!-- path: language/introduction.md -->
## はじめに

MoonBit プログラムは、次のようなトップレベル定義から構成されます：

- 型定義
- 関数定義
- 定数定義と変数束縛
- `init` 関数、`main` 関数、`test` ブロック

### 式と文

MoonBit では文と式を区別します。関数本体では最後の句だけが式であり、それが戻り値になります。例えば：

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

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

式には次のものが含まれます：

- 値リテラル（例：真偽値、数値、文字、文字列、配列、タプル、構造体）
- 算術演算、論理演算、比較演算
- 配列要素（例：`a[0]`）、構造体フィールド（例：`r.x`）、タプル要素（例：`t.0`）などへのアクセス
- 変数と（先頭が大文字の）enum コンストラクタ
- 無名ローカル関数定義
- `match`、`if`、`loop` 式など

文には次のものが含まれます：

- 名前付きローカル関数定義
- ローカル変数束縛
- 代入
- `return` 文
- 戻り値の型が `Unit` の式（例：`ignore`）

コードブロックには複数の文と 1 つの式を含められ、その式の値がコードブロックの値になります。

### 変数束縛

変数は `let mut` または `let` を使って、それぞれ可変または不変として宣言できます。可変変数には新しい値を再代入できますが、不変変数にはできません。

定数はトップレベルでのみ宣言でき、変更できません。

```moonbit
let zero = 0

const ZERO = 0

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

##### NOTE
トップレベルの変数束縛は、

- **明示的な**型注釈が必要です（文字列、バイト、数値などのリテラルで定義する場合を除く）
- 可変にはできません（代わりに `Ref` を使ってください）

### 命名規則

変数名と関数名は小文字の `a-z` で始める必要があり、文字、数字、アンダースコア、その他の非 ASCII Unicode 文字を含められます。snake_case を使うことを推奨します。

定数名と型名は大文字の `A-Z` で始める必要があり、文字、数字、アンダースコア、その他の非 ASCII Unicode 文字を含められます。PascalCase または SCREAMING_SNAKE_CASE を使うことを推奨します。

#### キーワード

以下はキーワードであり、識別子として使用できません：

```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",
]
```

#### 予約語

以下は予約語です。使用すると警告が出ます。将来的にキーワードになる可能性があります。

```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",
]
```

### プログラムのエントリ

#### `init` と `main`

`init` 関数という特別な関数があります。`init` 関数には次の特徴があります：

1. 引数リストも戻り値型も持ちません。
2. 同じパッケージ内に複数の `init` 関数を定義できます。
3. `init` 関数は、他の関数から明示的に呼び出したり参照したりできません。代わりに、パッケージ初期化時にすべての `init` 関数が暗黙的に呼び出されます。したがって、`init` 関数は文のみで構成する必要があります。

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

`main` 関数という別の特別な関数もあります。`main` 関数はプログラムの主エントリであり、初期化段階の後に実行されます。

`init` 関数と同様に、引数リストも戻り値型も持ちません。

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

前の 2 つのコード例は、実行時に次を出力します：

```bash
1
2
```

このような `main` 関数を定義できるのは `main` パッケージだけです。詳しくは [ビルドシステムチュートリアル](../toolchain/moon/tutorial.md) を参照してください。現在のプロジェクトでは、これは `moon.pkg` で次のように設定します：

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

#### `test`

`test` ブロックというトップレベル構造もあります。`test` ブロックでは次のようにインラインテストを定義できます：

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

以降では `test` ブロックと `main` 関数を使って実行結果を示します。特に断りがない限り、すべての `test` ブロックは成功すると仮定します。

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

### 組み込みデータ構造

#### Unit

MoonBit の組み込み型 `Unit` は、意味のある値が存在しないことを表します。値は 1 つだけで、`()` と書きます。`Unit` は C/C++/Java などの言語における `void` に似ていますが、`void` とは異なり実際の型であり、型が期待される場所ならどこでも使えます。

`Unit` 型は、何らかの処理を行うものの意味のある結果を返さない関数の戻り値型としてよく使われます：

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

MoonBit では `Unit` は第一級の型として扱われるため、ジェネリクスで使ったり、データ構造に格納したり、関数の引数として渡したりできます。

#### Boolean

MoonBit には組み込みの真偽値型があり、値は `true` と `false` の 2 つです。真偽値型は条件式や制御構造で使われます。`!` を使うと真偽値を反転できます。`not(x)` も同じ意味です。

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

#### 数値

MoonBit には整数型と浮動小数点数型があります：

| 型        | 説明                              | 例                          |
|----------|---------------------------------|----------------------------|
| `Int16`  | 16 ビット符号付き整数                    | `(42 : Int16)`             |
| `Int`    | 32 ビット符号付き整数                    | `42`                       |
| `Int64`  | 64 ビット符号付き整数                    | `1000L`                    |
| `UInt16` | 16 ビット符号なし整数                    | `(14 : UInt16)`            |
| `UInt`   | 32 ビット符号なし整数                    | `14U`                      |
| `UInt64` | 64 ビット符号なし整数                    | `14UL`                     |
| `Double` | IEEE 754 によって定義された 64 ビット浮動小数点数 | `3.14`                     |
| `Float`  | 32 ビット浮動小数点数                    | `(3.14 : Float)`           |
| `BigInt` | 他の型より大きな数値を表します                 | `10000000000000000000000N` |

MoonBit は、10 進数、2 進数、8 進数、16 進数を含む数値リテラルもサポートしています。

可読性を高めるために、`1_000_000` のように数値リテラルの途中にアンダースコアを入れられます。アンダースコアは 3 桁ごとだけでなく、数値の任意の位置に置けます。

- 10 進数では、数字の間にアンダースコアを入れられます。

  デフォルトでは、整数リテラルは符号付き 32 ビット数として扱われます。符号なし数値には接尾辞 `U` が、64 ビット数値には接尾辞 `L` が必要です。
  ```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
  ```
- 2 進数は先頭に 0 があり、その後に文字 `B` が続く形式、つまり `0b` / `0B` です。`0b` / `0B` の後の桁は `0` または `1` でなければなりません。
  ```moonbit
  let bin = 0b110010
  let another_bin = 0B110010
  ```
- 8 進数は先頭に 0 があり、その後に文字 `O` が続く形式、つまり `0o` / `0O` です。`0o` / `0O` の後の桁は `0` から `7` の範囲でなければなりません：
  ```moonbit
  let octal = 0o1234
  let another_octal = 0O1234
  ```
- 16 進数は先頭に 0 があり、その後に文字 `X` が続く形式、つまり `0x` / `0X` です。`0x` / `0X` の後の桁は `0123456789ABCDEF` の範囲でなければなりません。
  ```moonbit
  let hex = 0XA
  let another_hex = 0xA_B_C
  ```
- 浮動小数点数リテラルは 64 ビット浮動小数点数です。`Float` を定義するには型注釈が必要です。
  ```moonbit
  let double = 3.14 // Double
  let float : Float = 3.14
  let float2 = (3.14 : Float)
  ```

  64 ビット浮動小数点数は 16 進数形式でも定義できます：
  ```moonbit
  let hex_double = 0x1.2P3 // (1.0 + 2 / 16) * 2^(+3) == 9
  ```

期待される型が分かっている場合、MoonBit はリテラルを自動的にオーバーロードできるため、文字接尾辞で数値型を指定する必要はありません：

```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` は UTF-16 コードユニットの列を保持します。ダブルクォートで文字列を作成することも、`#|` を使って複数行文字列を書くこともできます。

```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

```

ダブルクォートの文字列では、バックスラッシュの後に特定の特殊文字を続けるとエスケープシーケンスになります：

| エスケープシーケンス           | 説明                 |
|----------------------|--------------------|
| `\n`、`\r`、`\t`、`\b`  | 改行、復帰、水平タブ、バックスペース |
| `\\`                 | バックスラッシュ           |
| `\u5154`、`\u{1F600}` | Unicode エスケープシーケンス |

MoonBit は文字列補間をサポートしています。補間文字列の中に変数を埋め込めます。この機能により、変数の値をテキストに直接埋め込んで動的な文字列を作りやすくなります。文字列補間に使う変数は [`Show` トレイト](methods.md#builtin-traits) を実装している必要があります。

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

##### NOTE
補間式には改行、`{}`、`"` を含められません。

複数行文字列は先頭に `#|` または `$|` を付けて定義できます。前者は生文字列をそのまま保持し、後者はエスケープと補間を行います：

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

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

同じ複数行文字列の中で `$|` と `#|` を混在させないでください。ブロック全体でどちらか一方のスタイルに統一してください。

[VSCode 拡張機能](../toolchain/vscode/index.md#actions) には、貼り付けた文書を通常の複数行文字列に変換したり、通常テキストと MoonBit の複数行文字列を切り替えたりできるアクションがあります。

期待される型が `String` の場合、配列リテラル構文は文字列中の各文字を指定して `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` は Unicode のコードポイントを表します。

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

文字リテラルは、期待される型が `Int` または `UInt16` の場合、その型にオーバーロードできます：

```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)

MoonBit のバイトリテラルは、1 つの ASCII 文字または 1 つのエスケープからなり、`b'...'` の形式を取ります。バイトリテラルの型は `Byte` です。例えば：

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

```default
97
255
```

`Bytes` は不変なバイト列です。バイトと同様に、bytes リテラルは `b"..."` の形式を取ります。例えば：

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

バイトリテラルと bytes リテラルもエスケープシーケンスをサポートしますが、文字列リテラルのものとは異なります。次の表は、byte / bytes リテラルでサポートされるエスケープシーケンスです：

| エスケープシーケンス          | 説明                 |
|---------------------|--------------------|
| `\n`、`\r`、`\t`、`\b` | 改行、復帰、水平タブ、バックスペース |
| `\\`                | バックスラッシュ           |
| `\x41`              | 16 進数エスケープシーケンス    |
| `\o102`             | 8 進数エスケープシーケンス     |

##### NOTE
`@buffer.T` を使うと、さまざまな種類のデータを書き込んで bytes を構築できます。例えば：

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

配列リテラルも、並びの各 byte を指定することで `Bytes` 列を構築するようにオーバーロードできます。

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

##### SEE ALSO
Byte の API: [https://mooncakes.io/docs/moonbitlang/core/byte](https://mooncakes.io/docs/moonbitlang/core/byte)   Bytes の API: [https://mooncakes.io/docs/moonbitlang/core/bytes](https://mooncakes.io/docs/moonbitlang/core/bytes)   @buffer.T の API: [https://mooncakes.io/docs/moonbitlang/core/buffer](https://mooncakes.io/docs/moonbitlang/core/buffer)

[Overloaded Literals]()

##### バイトコンテナの選び方

MoonBit にはバイト指向のコンテナ型がいくつかあります。互いに関連していますが、役割は異なります：

| Type                 | 所有権 / 可変性    | サイズ変更可   | 主な用途                                  |
|----------------------|--------------|----------|---------------------------------------|
| `Bytes`              | 所有権あり，不変     | いいえ      | 最終的な byte ペイロード、API 境界、シリアライズ済みデータ    |
| `BytesView`          | 借用された不変ビュー   | いいえ      | 既存の bytes をコピーせずにスライスまたはパースする         |
| `Array[Byte]`        | 所有権あり，可変     | はい       | 汎用の可変 byte ストレージ                      |
| `FixedArray[Byte]`   | 所有権あり，可変     | いいえ      | 固定サイズの作業バッファ                          |
| `ArrayView[Byte]`    | 借用された配列ビュー   | いいえ      | 所有権を持たずに配列ベースの byte ストレージのスライスを渡す     |
| `MutArrayView[Byte]` | 借用された可変ビュー   | いいえ      | 借用した配列ベースの byte ストレージをその場で変更する        |
| `@buffer.Buffer`     | 所有権あり，可変ビルダー | はい       | bytes を段階的に構築し、最後に `contents()` を呼び出す |

特に重要なのは次の 2 つの違いです：

- `Bytes` と `BytesView` の違い：所有された不変データと、借用された不変スライス。
- `Array[Byte]` と `ArrayView[Byte]` / `MutArrayView[Byte]` の違い：所有された可変ストレージと、それに対する借用された読み取り専用または可変ビュー。

`ReadOnlyArray[Byte]` と `MutArrayView[Byte]` は、それぞれの制約を明示したい場合に使う対応する読み取り専用/可変ビュー型です。パターンマッチとビット文字列パースもこれらのバイトコンテナで使えます。詳細は [Array Pattern]() と [Bitstring Pattern]() を参照してください。

#### タプル

タプルは、カンマ `,` で要素を区切り、丸括弧 `()` で構成される有限個の値の集合です。要素の順序は重要です。例えば `(1,true)` と `(true,1)` は異なる型になります。例を示します：

```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
```

タプルはパターンマッチまたは添字でアクセスできます：

```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

`Ref[T]` は、型 `T` の値 `val` を保持する可変参照です。

`{ val : x }` で構築でき、`ref.val` でアクセスできます。詳細は [struct]() を参照してください。

```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

MoonBit で起こりうるエラーや失敗を表す最も一般的な型が `Option` と `Result` です。

- `Option[T]` は、型 `T` の値が存在しない可能性を表します。`T?` と略記できます。
- `Result[T, E]` は、型 `T` の値か型 `E` のエラーのいずれかを表します。

詳細は [enum]() を参照してください。

```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
`Option` の API: [https://mooncakes.io/docs/moonbitlang/core/option](https://mooncakes.io/docs/moonbitlang/core/option)   `Result` の API: [https://mooncakes.io/docs/moonbitlang/core/result](https://mooncakes.io/docs/moonbitlang/core/result)

#### 配列

配列は、角括弧 `[]` で構成され、要素をカンマ `,` で区切る有限個の値の列です。例えば：

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

`numbers[x]` を使って x 番目の要素を参照できます。インデックスは 0 から始まります。

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

`Array[T]` と `FixedArray[T]` があります。ビューは `ArrayView[T]` と `MutArrayView[T]` で提供されます（下記参照）。

`Array[T]` はサイズを伸ばせますが、`FixedArray[T]` は固定サイズなので、初期値を与えて作成する必要があります。

##### WARNING
`FixedArray` を同じ初期値で作成するのはよくある落とし穴です：

```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)
}
```

これは、すべてのセルが同じオブジェクト（この場合は `FixedArray[Int]`）を参照しているためです。代わりに `FixedArray::makei()` を使うと、各インデックスごとに個別のオブジェクトが作られます。

```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)
}
```

期待される型が分かっている場合、MoonBit は配列リテラルを自動的にオーバーロードできます。そうでない場合は `Array[T]` が生成されます：

```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

他の言語の `slice` と同様に、ビューはコレクションの特定区間への参照です。`data[start:end]` を使うと、配列 `data` の `start` から `end`（終端は含まない）までを参照するビューを作れます。`start` と `end` の両方は省略できます。

##### NOTE
`ArrayView` 自体は不変データ構造ですが、元の `Array` や `FixedArray` は変更されうる場合があります。可変ビューが必要なら、`data.mut_view(...)` で `MutArrayView[T]` を使ってください。

```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 の標準ライブラリには、挿入順を保持する `Map` というハッシュマップ型があります。`Map` は便利なリテラル構文で作成できます：

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

現在、Map リテラル構文のキーは定数である必要があります。`Map` はパターンマッチでもきれいに分解でき、[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 はリテラルのオーバーロードによって、便利な JSON 処理をサポートします。式の期待型が `Json` のとき、数値・文字列・配列・Map リテラルをそのまま JSON データとして使えます：

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

`Json` 値もパターンマッチできます。[Json Pattern]() を参照してください。

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

[Overloaded Literals]()

### オーバーロードされたリテラル

オーバーロードされたリテラルを使うと、同じ構文で異なる型の値を表現できます。例えば `1` は、期待型に応じて `UInt` や `Double` を表せます。期待型が分からない場合、リテラルは既定で `Int` として解釈されます。

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

}

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

オーバーロードされたリテラルは組み合わせられます。配列リテラルを `Bytes` に、数値リテラルを `Byte` にオーバーロードできるなら、`[1,2,3]` を `Bytes` としても解釈できます。MoonBit におけるオーバーロードされたリテラルの表は次のとおりです：

| オーバーロードされたリテラル                                              | 既定の型       | オーバーロード先                                                                          |
|-------------------------------------------------------------|------------|-----------------------------------------------------------------------------------|
| `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) |

パターンにも同様のオーバーロード規則があります。詳しくは [Pattern Matching]() を参照してください。

##### NOTE
リテラルのオーバーロードは値変換とは異なります。変数を別の型へ変換するには、`to_int()` や `to_double()` など、`to_` で始まるメソッドを使ってください。

#### オーバーロードされたリテラル内のエスケープシーケンス

エスケープシーケンスは、オーバーロードされた `"..."` リテラルと `'...'` リテラルで使えます。エスケープシーケンスの解釈は、オーバーロード先の型によって異なります：

- 基本エスケープシーケンス

  `\n`、`\r`、`\t`、`\\`、`\b` です。これらは任意の `"..."` または `'...'` リテラルで使えます。`String` や `Bytes` では、それぞれ対応する `Char` または `Byte` として解釈されます。
- バイトエスケープシーケンス

  `\x41` と `\o102` のエスケープシーケンスは `Byte` を表します。これらは `Bytes` と `Byte` にオーバーロードされるリテラルで使えます。
- Unicode エスケープシーケンス

  `\u5154` と `\u{1F600}` のエスケープシーケンスは `Char` を表します。これらは `String` と `Char` 型のリテラルで使えます。

### 関数

関数は引数を受け取り、結果を返します。MoonBit では関数は第一級値なので、他の関数の引数や戻り値にできます。MoonBit の命名規則では、関数名を大文字 `A-Z` で始めてはいけません。下の `enum` 節でコンストラクタと比較してください。

#### トップレベル関数

関数はトップレベルでもローカルでも定義できます。たとえば、`fn` キーワードを使って 3 つの整数を合計し、その結果を返すトップレベル関数は次のように定義できます：

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

トップレベル関数の引数と戻り値には、**明示的な**型注釈が必要です。

トップレベル関数とメソッドは `declare` で導入することもできます。宣言された関数はシグネチャだけを持ち、本体は持ちません。後から置く実装はそのシグネチャと一致している必要があります。実装を置く前に API の形を先に利用可能にしたい場合に便利です。

```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)
}
```

宣言された関数に実装がある場合、宣言と実装は関数名、可視性、型パラメータ、パラメータ、戻り値の型、エフェクトについて一致している必要があります。

#### ローカル関数

ローカル関数は名前付きにも無名にもできます。ローカル関数定義では型注釈を省略でき、多くの場合自動で推論されます。例えば：

```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)
}
```

単純な無名関数には、MoonBit は 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))
```

ローカル関数では引数型と戻り値型の推論はできますが、*effect 推論* は arrow function 構文でのみサポートされます。`fn` が [error を送出](error-handling.md) したり [非同期処理を実行](async-experimental.md) したりする場合は、`raise` または `async` を明示的に付ける必要があります。

関数は、名前付きでも無名でも `_lexical closure_` です。ローカル束縛を持たない識別子は、外側の字句スコープにある束縛を参照しなければなりません。例えば：

```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))
}
```

ローカル関数は、自分自身と、先に定義された他のローカル関数だけを参照できます。相互再帰するローカル関数を定義するには、代わりに `letrec f = .. and g = ..` の構文を使います：

```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)
```

#### 関数適用

関数は、括弧内の引数リストに適用できます：

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

これは、`add3` が前の例のように名前付き関数として定義されていても、下の例のように関数値に束縛された変数であっても同じです：

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

式 `add3(1, 2, 7)` は `10` を返します。関数値として評価される式なら、どれでも適用できます：

```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)
}
```

#### 部分適用

部分適用は、関数の一部の引数だけを与えて、残りの引数を受け取る新しい関数を得る手法です。MoonBit では、関数適用で `_` 演算子を使うことで部分適用できます：

```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
}
```

`_` 演算子は、括弧内で欠けている引数を表します。部分適用では同じ括弧内に複数の `_` を使えます。例えば `Array::fold(_, _, init=5)` は `fn(x, y) { Array::fold(x, y, init=5) }` と等価です。

`_` 演算子は、enum の生成、ドット記法の関数呼び出し、パイプラインでも使えます。

##### WARNING
部分適用に `f(a, _, b)` という構文を使うことは非推奨です。代わりに `x => f(a, x, b)` を使ってください。

#### ラベル付き引数

**トップレベル**関数は、`label~ : Type` という構文でラベル付き引数を宣言できます。`label` は関数本体内での引数名にもなります：

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

ラベル付き引数は `label=arg` の構文で渡せます。`label=label` は `label~` と省略できます：

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

ラベル付き引数は任意の順序で渡せます。引数の評価順は、関数宣言におけるパラメータ順と同じです。

#### Optional arguments

引数は、`label?: Type = default_expr` という構文でデフォルト式を与えることで省略可能にできます。`default_expr` は省略してもかまいません。この引数が呼び出し時に与えられない場合、デフォルト式が使われます：

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

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

デフォルト式は、使われるたびに毎回評価されます。デフォルト式に副作用があれば、それも実行されます。例えば：

```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)
}
```

省略可能引数の値は、呼び出し側では通常の式です。`raise` や `async` の文脈では、エラーを送出する可能性がある式や非同期関数呼び出しを渡せます：

```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")
}
```

非同期関数では、省略可能引数の式でも通常どおり非同期関数を呼び出せます：

```moonbit

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

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

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

デフォルト式の結果を複数の関数呼び出しで共有したい場合は、デフォルト式をトップレベルの `let` 宣言に持ち上げられます：

```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)
}
```

デフォルト式は、前の引数に依存することもできます。例えば：

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

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

##### デフォルト値のない省略可能引数

ユーザーが値を指定しない場合に別の意味を持たせたいことはよくあります。デフォルト値のない省略可能引数は型 `T?` を持ち、既定値は `None` です。この種の省略可能引数を直接渡すと、MoonBit は値を自動的に `Some` で包みます：

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

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

ときには、`T?` 型の値をそのまま渡したい場合もあります。たとえば省略可能引数を転送するときです。MoonBit ではこれ用に `label?=value` という構文があり、`label?` は `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>

#### 自動補完引数

MoonBit では、関数呼び出しのソース位置のように、特定の型の引数を呼び出し箇所ごとに自動で埋められます。自動補完引数を宣言するには、ラベル付き引数を宣言し、関数属性 `#callsite(autofill(param_a, param_b))` を追加するだけです。引数が明示的に与えられない場合、MoonBit は呼び出し箇所で自動的に補完します。

現在 MoonBit がサポートする自動補完引数は 2 種類です。`SourceLoc` は関数呼び出し全体のソース位置、`ArgsLoc` は各引数のソース位置を（あれば）含む配列です：

```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]
}
```

自動補完引数は、デバッグ用やテスト用のユーティリティを書くのにとても便利です。

#### 関数エイリアス

MoonBit では、関数エイリアスを使って関数を別名で呼び出せます。関数エイリアスは次のように宣言します：

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

`visibility` フィールドを使うと、可視性の異なる関数エイリアスも作れます。

### 制御構造

#### 条件式

条件式は、条件、then 節、そして省略可能な `else` 節または `else if` 節から構成されます。

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

then 節を囲む中括弧は必須です。

条件式は MoonBit では常に値を返し、then 節と else 節の戻り値は同じ型でなければならないことに注意してください。例を示します：

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

`else` 節を省略できるのは、戻り値の型が `Unit` の場合だけです。

#### match 式

`match` 式は条件式に似ていますが、どの分岐を評価するかを決めるために [pattern matching]() を使い、同時に変数の抽出も行います。

```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")
}
```

可能な条件が省略されていると、コンパイラは警告を出し、そのケースに到達するとプログラムは終了します。

#### guard 文

`guard` 文は、指定した不変条件を確認するために使います。不変条件が満たされていれば、プログラムは後続の文の実行を続け、そのまま戻ります。条件が満たされない場合、つまり false の場合は、`else` ブロック内のコードが実行され、その評価結果が返されます（後続の文はスキップされます）。

```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 文と is 式

`let` 文は [pattern matching]() と組み合わせて使えます。しかし、`let` 文で扱えるのは 1 つのケースだけです。ここで `guard` 文と [is 式]() を組み合わせると、この問題を解決できます。

次の例では、`getProcessedText` は入力 `path` がすべてプレーンテキストであるリソースを指すことを前提にし、プレーンテキストのリソースを取り出しながら `guard` 文でこの不変条件を保証しています。`match` 文を使う場合と比べて、その後の `text` の処理は 1 段階浅いインデントで書けます。

```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)
}
```

`else` 部分を省略すると、`guard` 文で指定した条件が真でないか、またはマッチできない場合にプログラムは終了します。

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

#### while ループ

MoonBit では、`while` ループを使うと、条件が真である限りコードブロックを繰り返し実行できます。条件はコードブロックを実行する前に評価されます。`while` ループは `while` キーワードの後に条件とループ本体を続けて定義します。ループ本体は文の列であり、条件が真である限り実行されます。

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

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

ループ本体では `break` と `continue` を使えます。`break` を使うと現在のループを抜けられ、`continue` を使うと現在の反復の残りを飛ばして次の反復に進みます。

```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
```

`while` ループは省略可能な `nobreak` 節もサポートします。ループ条件が false になると `nobreak` 節が実行され、その後ループは終了します。

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

```default
2
1
0
```

`nobreak` 節がある場合、`while` ループは値を返すこともできます。戻り値は `nobreak` 節の評価結果です。この場合、`break` でループを抜けるなら `break` の後に戻り値を指定する必要があり、その型は `nobreak` 節の戻り値と同じでなければなりません。

```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 ループ

MoonBit は C 言語風の for ループもサポートします。`for` キーワードの後に、変数初期化節、ループ条件、更新節がセミコロンで区切られて続きます。これらは括弧で囲む必要はありません。例えば、次のコードは新しい変数束縛 `i` を作成し、これはループ全体で有効かつ不変です。これにより、明快なコードを書きやすくなり、理解もしやすくなります：

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

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

変数初期化節では複数の束縛を作成できます：

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

更新節では、束縛変数が複数ある場合、それらは同時に更新されることに注意してください。つまり、上の例では更新節は `i = i + 1`、`j = j + 1` を順番に実行するのではなく、`i` と `j` を同時に増やします。したがって、更新節で束縛変数の値を読むと、常に前回の反復で更新された値が得られます。

変数初期化節、ループ条件、更新節はすべて省略可能です。例えば、次の 2 つは無限ループです：

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

`for` ループも `continue`、`break`、`nobreak` 節をサポートします。`while` ループと同様に、`for` ループも `break` と `nobreak` 節を使って値を返せます。

`continue` 文は `for` ループの現在の反復の残り（更新節を含む）を飛ばして次の反復に進みます。`continue` 文は、束縛変数の個数に一致する式をカンマ区切りで続けることで、`for` ループの束縛変数も更新できます。

例えば、次のプログラムは 1 から 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` ループ

MoonBit では `for .. in` ループ構文を使って、さまざまなデータ構造やシーケンスの要素を走査できます：

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

`for .. in` ループは MoonBit の標準ライブラリにある `Iter` の利用に変換されます。`.iter() : Iter[T]` メソッドを持つ型なら、`for .. in` で走査できます。`Iter` 型の詳細は、下の [Iterator]() を参照してください。

`for .. in` ループは、次のような整数列の反復もサポートします：

```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)
}
```

1 つの値からなるシーケンスに加えて、MoonBit は `Map` のような 2 つの値からなるシーケンスも、標準ライブラリの `Iter2` 型を通じて走査できます。`.iter2() : Iter2[A, B]` メソッドを持つ型なら、2 つのループ変数を使う `for .. in` で走査できます：

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

2 つのループ変数を使う `for .. in` の別の例として、配列の添字を追跡しながら配列を走査することができます：

```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
```

`return`、`break`、エラー処理などの制御フロー操作は、`for .. in` ループの本体でも使えます：

```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
```

ループ変数が不要なら、`_` で無視できます。

#### `for .. in` ループの範囲式

`for .. in` ループは範囲式と組み合わせて、数値範囲を反復することもできます：

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

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

`for .. in` ループで使える範囲式には 4 種類あります：

- `a..<b`: `a` から `b` まで昇順で反復し、`b` を含まない
- `a..<=b`: `a` から `b` まで昇順で反復し、`b` を含む
- `a>..b`: `a` から `b` まで降順で反復し、`a` を含まない
- `a>=..b`: `a` から `b` まで降順で反復し、`a` を含む

#### リスト内包表記

MoonBit は、別のコレクションや範囲を反復してコレクションを構築するリスト内包表記をサポートします：

```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 ]
```

構文は `[ for ... => ... ]` です。`=>` より前の部分は `for .. in` と同じ反復規則に従います。束縛が 1 つなら `Iter`、2 つなら `Iter2` を使い、`0..<10` のような範囲式も使えます。任意の `if` ガードで、結果式を評価する前に要素をフィルタできます。ガード内の `is` 式で導入された名前、たとえば上の `y` は結果式で使えます。

期待される型がない場合、結果は既定で `Array[T]` になります。期待される型が分かっている場合、リスト内包表記は `FixedArray[T]`、`ReadOnlyArray[T]`、`String`、`Bytes`、`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 ]
```

遅延列や無限列には、`Iter[T]` を直接作成します。次のイテレータは、捕捉した変数にフィボナッチ数列の状態を保持し、収集する前に長さを制限しています：

```moonbit
let mut p1 = 1
let mut p2 = 0
let fib_numbers : Iter[Int] = Iter::new(fn() {
  let next = p1
  p1 = p1 + p2
  p2 = next
  Some(next)
})
let first_six = fib_numbers.take(6).collect()
```

リスト内包表記の内部では、`return`、`break`、`continue` などの制御フロー操作は使えません。

#### ラベル付き continue/break

ループにラベルを付けると、ネストしたループの中から `break` や `continue` で参照できます。例えば：

```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` 式

`defer` 式は、確実なリソース解放を行うために使えます。`defer` の構文は次のとおりです：

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

プログラムが `body` を抜けるたびに、`expr` が実行されます。例えば、次のプログラムでは：

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

まず `do things with the resource` が出力され、その後に `perform resource cleanup` が出力されます。`defer` 式は、body がどのように終了しても必ず実行されます。[error](error-handling.md) を扱えるほか、`return`、`break`、`continue` を含む制御フロー構文にも対応します。

連続した `defer` は逆順で実行されます。例えば、次のコードでは：

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

まず `do things`、次に `second defer`、最後に `first defer` が出力されます。

`defer` の右辺では `return`、`break`、`continue` は使えません。現在のところ、`defer` の右辺でエラーを送出することや `async` 関数を呼ぶことも禁止されています。

### イテレータ

イテレータは、要素へのアクセスを提供しながらシーケンスを走査するオブジェクトです。Java の `Iterator<T>` のような従来の OO 言語では、`next()` と `hasNext()` を使って反復処理を進めます。一方、関数型言語（JavaScript の `forEach`、Lisp の `mapcar`）では、操作とシーケンスを受け取り、その操作をシーケンスに適用しながら消費する高階関数を使います。前者は  *外部イテレータ*（利用者から見える）、後者は  *内部イテレータ*（利用者から見えない）と呼ばれます。

組み込み型 `Iter[T]` は MoonBit の外部イテレータ実装です。`next()` を公開して次の値を取り出します。`Some(value)` を返してイテレータを進め、反復が終わると `None` を返します。ほとんどの組み込み順次データ構造は `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)
}
```

よく使うメソッドには次のようなものがあります：

- `each`: イテレータの各要素を反復し、それぞれに関数を適用します。
- `fold`: 与えられた関数でイテレータの要素を畳み込み、与えられた初期値から開始します。
- `collect`: イテレータの要素を配列に集めます。
- `filter`: *lazy* 述語関数に基づいてイテレータの要素をフィルタします。
- `map`: *lazy* マッピング関数を使ってイテレータの要素を変換します。
- `concat`: *lazy* 2 つのイテレータを結合し、2 つ目の要素を 1 つ目の後ろに連結します。

`filter` や `map` のようなメソッドは、Array のようなシーケンスオブジェクトで非常によく使われます。しかし `Iter` が特別なのは、新しい `Iter` を構築するメソッドがすべて *lazy* であることです（つまり、関数の中に包まれているため、呼び出しただけでは反復は始まりません）。その結果、中間値のための確保が不要になります。これが `Iter` をシーケンス走査に適したものにしている理由で、余分なコストがありません。MoonBit では、シーケンスオブジェクトそのものではなく `Iter` を関数間で受け渡すことを推奨します。

`Array` のような定義済みのシーケンス構造とそのイテレータだけで、たいていは十分です。しかし、要素型 `S` の独自シーケンスでこれらのメソッドを活用するには、`Iter` を実装する必要があります。つまり、`Iter[S]` を返す関数です。`Bytes` を例に取ると：

```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
    }
  })
}
```

イテレータは 1 回限りです。`next()` を呼ぶか、`each`、`fold`、`collect` などのメソッドで消費すると、内部状態は進み、リセットできません。同じシーケンスをもう一度走査したい場合は、元のソースから新しい `Iter` を取得してください。

### カスタムデータ型

新しいデータ型を作る方法は `struct` と `enum` の 2 つです。

#### struct

MoonBit の struct は tuple に似ていますが、フィールドは名前で管理されます。struct は struct リテラルで構築でき、ラベル付きの値の集合を中括弧で囲みます。フィールドが型定義と完全に一致していれば、struct リテラルの型は自動推論されます。フィールドにはドット構文 `s.f` でアクセスできます。フィールドに `mut` キーワードが付いていれば、新しい値を代入できます。

```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
```

##### 省略記法で struct を構築する

`name` や `email` のような変数がすでにあるなら、struct を構築するときにそれらの名前を繰り返すのは冗長です。代わりに省略記法を使えます。振る舞いはまったく同じです：

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

同じフィールドを持つ他の struct がないなら、構築時に struct 名を付けるのは冗長です：

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

##### struct 更新構文

既存の struct を元にして、いくつかのフィールドだけ更新した新しい struct を作ると便利です。

```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 }
```

##### struct のカスタムコンストラクタ

MoonBit では、すべての `struct` 型に対してカスタムコンストラクタも定義できます。コンストラクタは struct 名で呼び出して値を作成できる特別なメソッドです。まず通常どおり struct を定義します：

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

次に、struct 型と同じ名前のメソッドとしてコンストラクタを実装します。戻り値はその struct 自身でなければなりません：

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

`struct` がコンストラクタを宣言していれば、名前で直接構築できます：

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

コンストラクタ呼び出しはコンストラクタメソッドのシグネチャに従うため、ラベルのない引数は馴染みのある `TypeName(value)` 形式で書けます。

コンストラクタでも、通常の関数と同じようにラベル付き引数やオプション引数を使えます：

```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 }")
```

struct コンストラクタは通常の関数として実装されるため、エラーを送出することもできます：

```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
  try Positive(10) catch {
    error => debug_inspect(error, content="NegativeInput")
  } noraise {
    value => debug_inspect(value, content="{ value: 10 }")
  }
  try Positive(-1) catch {
    error => debug_inspect(error, content="NegativeInput")
  } noraise {
    value => debug_inspect(value, content="{ value: -1 }")
  }
```

非同期コンストラクタは `async fn TypeName::TypeName` として宣言し、非同期コードの中で使えます：

```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 }")
}
```

`struct` コンストラクタで値を作成することは、[enum コンストラクタ]() とまったく同じ意味を持ちます。ただし、`struct` コンストラクタはパターンマッチには使えません。例えば、外部パッケージの `struct` をコンストラクタで作るとき、式の期待型が分かっていればパッケージ名は省略できます。

`struct` コンストラクタは通常の関数として実装されるため、[エラーを送出](error-handling.md)したり、[非同期操作](async-experimental.md)を実行したりできます。`struct` コンストラクタは [optional arguments]() もサポートします。オプション引数のデフォルト値は、通常の関数シグネチャと同じようにコンストラクタ実装に書きます。

#### Enum

enum 型は、関数型言語における代数的データ型に似ています。C/C++ に慣れている方は tagged union と呼ぶほうがしっくりくるかもしれません。

enum には複数のケース（コンストラクタ）を持てます。コンストラクタ名は大文字で始める必要があります。これらの名前を使って enum の対応するケースを構築したり、パターンマッチで enum 値がどの分岐に属するかを判定したりできます：

```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 のケースは payload データも持てます。ここでは、整数リスト型を 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
```

##### ラベル付き引数を持つコンストラクタ

enum コンストラクタはラベル付き引数を持てます：

```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
```

パターンマッチでは、コンストラクタのラベル付き引数にも struct フィールドのようにアクセスできます：

```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
```

##### 可変フィールドを持つコンストラクタ

コンストラクタに可変フィールドを定義することもできます。これは命令的なデータ構造を定義するときに特に便利です：

```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
    }
  }
}
```

##### 拡張可能 enum

`extenum` はオープンな enum 型を定義します。通常の `enum` とは異なり、`extenum` には後から、別パッケージからのものも含めて、さらにコンストラクタを追加できます。これは、あるパッケージが共有のイベント、メッセージ、または拡張ポイントとなる型を定義し、他のパッケージがそれぞれ独自のケースを提供したい場合に有用です。

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

同じパッケージ内の拡張可能 enum にコンストラクタを追加するには、`extenum Type += { ... }` を使います：

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

別パッケージの拡張可能 enum を拡張するには、その型を定義しているパッケージで対象の型を修飾します：

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

拡張可能 enum のコンストラクタは、そのコンストラクタを定義したパッケージで修飾されます。現在のパッケージのコンストラクタについては、期待される型が分かっている場合、コンストラクタ名をそのまま使用できます。別パッケージのコンストラクタについては、式やパターンの中で `@pkg.Constructor` を使います。拡張可能 enum 型とコンストラクタの由来の両方を明示したい場合は、コンストラクタを `@type_pkg.Type::@constructor_pkg.Constructor` と書きます。

あるパッケージが基底パッケージと拡張パッケージの両方を import すると、両方のパッケージから来る値は同じ拡張可能 enum 型を持ちます：

```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)
}
```

現在の宣言の外側でさらにコンストラクタを追加できるため、パターンマッチにはワイルドカード分岐を含める必要があります。

拡張できるのは `extenum` 宣言だけです。通常の `enum` 宣言は閉じています。

#### tuple struct

MoonBit では、tuple struct と呼ばれる特別な struct をサポートしています：

```moonbit
struct UserId(Int)

struct UserInfo(UserId, String)
```

tuple struct は、コンストラクタが 1 つだけの enum に似ています（そのコンストラクタ名は tuple struct 自身の名前と同じです）。そのため、コンストラクタで値を作成したり、パターンマッチで内部表現を取り出したりできます：

```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
```

パターンマッチのほかにも、タプルと同様にインデックスで要素へアクセスできます：

```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
```

#### 型エイリアス

MoonBit では `type NewType = OldType` という構文で型エイリアスを定義できます：

##### WARNING
古い構文 `typealias OldType as NewType` は将来削除される可能性があります。

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

上記の他の型宣言とは異なり、型エイリアスは新しい型を定義しません。定義とまったく同じように振る舞う型マクロにすぎません。そのため、型エイリアスに対して新しいメソッドを定義したり、trait を実装したりすることはできません。

#### ローカル型

MoonBit では、トップレベル関数の先頭で struct / enum を宣言できます。これらは現在のトップレベル関数の内部でのみ可視です。ローカル型はトップレベル関数のジェネリックパラメータを使えますが、追加のジェネリックパラメータを自分で導入することはできません。ローカル型は `derive` を使ってメソッドを導出できますが、手動で追加のメソッドを定義することはできません。例えば：

```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)
  ...
}
```

現在、ローカル型をエラー型として宣言することはできません。

### パターンマッチング

パターンマッチングを使うと、特定のパターンに一致させて、データ構造からデータを束縛できます。

#### 単純なパターン

式を次のものに対してパターンマッチできます：

- 真偽値、数値、文字、文字列などのリテラル
- 定数
- struct
- enum
- 配列
- map
- JSON

などです。一致した値を後で使えるように、識別子を定義して束縛することもできます。

```moonbit
const ONE = 1

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

関心のない値には `_` をワイルドカードとして使えます。また、struct・enum・配列の残りのフィールドを無視するには `..` を使えます（[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()
  }
}
```

特定のパターンに名前を付けるには `as` を使えます。また、`|` を使うと複数のケースを一度にマッチできます。1 つのパターン内で同じ変数名を 2 回束縛することはできず、`|` パターンの両側では同じ変数集合が束縛されている必要があります。

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

#### 配列パターン

配列パターンは、次の型に対してパターンマッチし、それぞれの要素やビューを取り出すために使えます：

| Type                                  | 要素   | ビュー          |
|---------------------------------------|------|--------------|
| Array[T], ArrayView[T], FixedArray[T] | T    | ArrayView[T] |
| Bytes, BytesView                      | Byte | BytesView    |
| String, StringView                    | Char | StringView   |

配列パターンには次の形があります：

- `[]` : 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")
}
```

配列パターンは、文字列を Unicode 安全に操作する方法を提供します。つまり、コードユニットの境界を尊重します。たとえば、文字列が回文かどうかを調べられます：

```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")
}
```

配列パターンの中に連続した char または byte 定数がある場合、パターンのスプレッド `..` 演算子でそれらをまとめて、コードをすっきりさせられます。なおこの場合、文字列または bytes 定数の後に続く `..` は要素数ちょうどに一致するため、1 回しか使えないという制約はありません。

```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', ..]
    }
  }
}
```

#### ビット列パターン

ビット列パターンは、バイトコンテナから詰め込まれたビットフィールドをマッチできます。`BytesView`、`Bytes`、`Array[Byte]`、`FixedArray[Byte]`、`ReadOnlyArray[Byte]`、`ArrayView[Byte]` でサポートされています。エンディアンを明確にするために、`be` / `le` 接尾辞で幅を明示してください。`be` は 1..64 の幅をサポートし、`le` はバイト境界に揃った幅（8 \* n）に対してのみ定義されます。これは little-endian の順序がバイト単位で定義されるためです。`..` がない場合、パターンはビュー全体を消費しなければなりません。

```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)
}
```

リテラルのビットパターンを使ってヘッダを検証し、`..` で残りのデータを次のパースステップに渡せます。

```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)
}
```

一般的なバイトコンテナでの例（`MutArrayView` スライスに注意）:

```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]") }
}
```

符号付きパターンは 2 の補数の意味で解釈されます。たとえば、`u1be` は `0` または `1` を返し、`i1be` は `0` または `-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)
}
```

結果型は幅によって異なります：

| 幅                    | 結果型            |
|----------------------|----------------|
| 1..32 bits (`u`/`i`) | `UInt` / `Int` |
| 33..64 bits (`u`)    | `UInt64`       |
| 33..64 bits (`i`)    | `Int64`        |

#### 範囲パターン

組み込みの整数型と `Char` では、値が特定の範囲に入るかどうかを MoonBit でマッチできます。

範囲パターンは `a..<b` または `a..=b` の形をとります。`..<` は上限を含まないことを、`..=` は上限を含むことを意味します。`a` と `b` には次のいずれかを指定できます：

- リテラル
- `const` で宣言された名前付き定数
- `_` は、この側に制約がないことを意味します

いくつか例を示します：

```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 パターン

MoonBit では、map のようなデータ構造に対して便利にマッチできます。map パターンの中では、`key : value` 構文は `key` が map に存在する場合に一致し、`key` の値をパターン `value` でマッチします。`key? : value` 構文は `key` の有無にかかわらず一致し、`value` は `map[key]`（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)).
- 現在、map パターンの key 部分はリテラルまたは定数でなければなりません
- map パターンは常に open です。マッチしなかった key は黙って無視され、この性質を明示するには `..` を追加する必要があります
- map パターンは効率的なコードにコンパイルされます。各 key は高々 1 回しか取得されません

#### Json パターン

マッチ対象の値の型が `Json` の場合は、リテラルパターンをコンストラクタと組み合わせて直接使えます：

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

#### ガード条件

パターンマッチ式の各 case にはガード条件を付けられます。ガード条件は、case がマッチするために真でなければならない真偽式です。ガード条件が偽なら、その case はスキップされ、次の case が試されます。例えば：

```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)
}
```

ガード条件は、match 式ですべてのパターンが網羅されているかをチェックするときには考慮されません。そのため、次の case では partial match の警告が表示されます：

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

##### WARNING
ガード条件の中で、マッチ対象の値の一部を変更する関数を呼ぶことは推奨されません。そのような場合、変更された部分は後続のパターンで再評価されません。注意して使ってください。

### ジェネリクス

ジェネリクスは、トップレベル関数とデータ型の定義でサポートされています。型パラメータは角括弧の中で導入できます。前述のデータ型 `List` に型パラメータ `T` を追加して、リストのジェネリック版を作り直すことができます。そうすると、`map` や `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))
  }
}
```

### 特殊構文

#### パイプライン

MoonBit には便利なパイプ構文 `x |> f(y)` と `f <| x` があり、通常の関数呼び出しを連結したり、ネストしたビルダー風コードを読みやすくしたりできます：

```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) + 1)
```

MoonBit のコードは *data-first* スタイルに従っています。つまり、関数は対象を第 1 引数に置きます。そのため、パイプ演算子は既定で左辺の値を右辺の関数呼び出しの第 1 引数に差し込みます。たとえば、`x |> f(y)` は `f(x, y)` と等価です。

`_` 演算子を使うと、`x |> f(y, _)` のように `f` の任意の引数位置に `x` を差し込めます。これは `f(y, x)` と等価です。ラベル付き引数も使えます。

パイプ演算子はアロー関数にもつなげられます。アロー関数にパイプするときは、関数本体を中括弧で囲む必要があります。たとえば `value |> x => { x + 1 }` です。

逆パイプ演算子は、右辺を左辺の呼び出しの最後の引数として適用します。たとえば、`f <| x` は `f(x)` と等価で、`f(a, b) <| c` は `f(a, b, c)` と等価です。これは DSL 風のコードで特に有用で、`div([text("hello")])` のようなネストした呼び出しを `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)))",
)
```

逆パイプは最後の引数を付け足すので、最後の引数がラムダである関数とも相性がよく、`section("toolbar") <| fn () { ... }` のような trailing-lambda スタイルを書けます。

#### カスケード演算子

カスケード演算子 `..` は、同じ値に対する可変操作を連続して行うために使います。構文は次のとおりです：

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

ここでは、`x..f()` は `{ x.f(); x }` と同じ意味です。

次のような場面を考えてみましょう。`write_string`、`write_char`、`write_object` などのメソッドを持つ `StringBuilder` 型では、同じ `StringBuilder` 値に対して一連の操作を行う必要がよくあります：

```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()
```

`builder` を何度もタイピングしないようにするため、そのメソッドはしばしば `self` 自身を返すように設計され、`.` 演算子で操作を連結できます。immutable な操作と mutable な操作を区別するために、MoonBit では `Unit` を返すすべてのメソッドに対して、戻り値型を変更せずに連続した操作を行うためにカスケード演算子を使えます。

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

#### `is` 式

`is` 式は、値が特定のパターンに一致するかどうかを調べます。`Bool` 値を返し、真偽値が期待される場所ならどこでも使えます。例えば：

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

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

`is` 式で導入されたパターン束縛は、次の文脈で使えます：

1. 真偽値の AND 式（`&&`）: 左辺の式で導入された束縛は、右辺の式で使えます
   ```moonbit
   fn f(x : Int?) -> Bool {
     x is Some(v) && v >= 0
   }
   ```
2. `if` 式の最初の分岐：条件が `e1 && e2 && ...` という真偽式の列である場合、`is` 式で導入された束縛は、条件が `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. `guard` 条件の後続の文では：
   ```moonbit
   fn h(x : Int?) -> Unit {
     guard x is Some(v)
     println(v)
   }
   ```
4. `while` ループ本体では：
   ```moonbit
   fn i(x : Int?) -> Unit {
     let mut m = x
     while m is Some(v) {
       println(v)
       m = None
     }
   }
   ```

`is` 式には単純なパターンしか指定できないことに注意してください。パターンを変数に束縛するために `as` を使いたい場合は、括弧を追加する必要があります。例えば：

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

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

#### 正規表現リテラル式

`re"..."` は正規表現リテラル式です。型は `Regex` です。

正規表現リテラルは通常の式なので、ローカル束縛に保存したり、引数として渡したり、デフォルト引数として使ったり、定数として定義したりできます：

```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` 値は `+` で連接、`|` で選択を表すように組み合わせることもできます。[`=~`]() のように正規表現の定数式が必要な場所では、正規表現リテラルから定義した名前付き `const` を直接参照できます。

通常の文字列リテラルとは異なり、正規表現リテラルではバックスラッシュを二重にエスケープする必要はありません。例えば `re"/\\*"` ではなく `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())
}
```

不正な正規表現リテラルはコンパイル時に拒否されます。

正規表現リテラルでは MoonBit の正規表現構文を使います。サポートされる形式は次のとおりです：

- リテラル文字：通常の文字はそのまま自分自身にマッチします
- ワイルドカード：`.` は改行を含む任意の 1 文字にマッチします
- 文字クラス：`[abc]`、`[^abc]`、`[a-z]`
- 文字クラス内の POSIX クラス：`[[:digit:]]`、`[[:alpha:]]`、`[[:space:]]`、`[[:word:]]`、`[[:xdigit:]]` など
- 量指定子：`*`、`+`、`?`、`{n}`、`{n,}`、`{n,m}`
- 非貪欲量指定子：`*?`、`+?`、`??`、`{n}?`、`{n,}?`、`{n,m}?`
- グループ化と選択：`( ... )`、`(?: ... )`、`(?<name> ... )`、`a|b`
- アサーション：`^`、`$`、`\b`、`\B`
- スコープ付き修飾子：`(?i: ... )` による大文字小文字を区別しないマッチ

エスケープは文字列ではなく正規表現の規則で解釈されます。一般的なものには `\n`、`\r`、`\t`、`\f`、`\v`、`\.` や `\(` のようなメタ文字のエスケープ、そして Unicode エスケープ `\uXXXX` / `\u{X...}` があります。リテラルの `{` にマッチさせたい場合は、`\{` ではなく `[{]` を使ってください。これは、将来 regex literal で補間をサポートするときの構文の余地を残すためです。`\{` は補間構文と衝突するためです。

重要な意味論と制限がいくつかあります：

- `^` と `$` はマルチラインではないアンカーで、入力全体の先頭と末尾にだけマッチします
- `\b` と `\B` は、正規表現リテラルを一級の `Regex` 値として扱う場合には現在利用できます。ですが、[`=~`]() のような `regex match expression` の定数コンテキストでは現時点では使えません。この制限は将来緩和される予定です。
- POSIX 文字クラスは ASCII ベースです
- `\d`、`\D`、`\s`、`\S`、`\w`、`\W` はサポートされません。代わりに `[[:digit:]]`、`[^[:digit:]]`、`[[:space:]]`、`[^[:space:]]`、`[[:word:]]`、`[^[:word:]]` を使ってください。
- `re"..."` では `\xHH` のバイトエスケープは使えません。代わりに Unicode エスケープか通常の文字を使ってください。
- 先読み、後読み、後方参照、文字クラスの集合演算はサポートされません
- 文字クラスでは `-` は範囲を表します。リテラルのハイフンにマッチさせたい場合は `\-` とエスケープしてください。`-` を文字クラスの先頭または末尾に置く書き方はサポートされません。

`(?<id>[0-9]+)` のような名前付きキャプチャグループは `Regex` 値自身の一部です。`Regex::execute` や `MatchResult::named_group` などの API では便利ですが、それ自体が MoonBit の束縛を導入するわけではありません。

正規表現リテラルを一級の `Regex` 値として使うとき、`Regex::execute` などの操作は first-match semantics を使います。つまり検索位置から見つかった最初のマッチを返し、longest-match モードは提供しません。

#### 正規表現マッチ式

正規表現マッチ式では `=~` 演算子を使って、regex 定数式で `StringView` を検索します。これは実験的な `lexmatch` を置き換えることを意図した新しい正規表現マッチ機能です。式の結果は `Bool` です。

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

右辺は正規表現の定数式でなければなりません。`re"abc"` のような正規表現リテラル、名前付き `const`、あるいは定数を `+` （連接）、`|`（選択）、括弧で組み立てた式が使えます。任意の実行時値は使えません。

マッチした部分文字列を束縛するには `as` を使います。未マッチの前置部分と後置部分を `StringView` として束縛するには `before` と `after` を使います。`before~` と `after~` は、それぞれ `before` と `after` という名前の変数を束縛する短縮形です。

これは正規表現の名前付きキャプチャグループとは別物です。例えば `re"(?<id>[0-9]+)"` では、`id` という名前は正規表現エンジンのキャプチャメタデータの一部であり、MoonBit の束縛ではありません。`=~` で束縛が必要な場合は、`(re"(?<id>[0-9]+)" as digits)` のように `as` を使ってください。

`is` と同様に、`=~` によって導入された束縛は `&&` の右辺や `if` の true 分岐など、同じブールフローの文脈で使えます。正規表現マッチはデフォルトで検索ベースなので、`"zabc!" =~ re"abc"` は `true` です。入力の先頭または末尾にマッチを制限したい場合は、`^` や `$` のようなアンカーを使ってください。

`=~` も first-match semantics を使います。設計上、longest-match の挙動はサポートしません。

```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"))
}
```

上の例では、`head`、`ident`、`tail`、`before`、`after`、`rest` の型はすべて `StringView` です。束縛 `ch` の型が `Char` になるのは、`re"."` がちょうど 1 文字にマッチするからです。

#### `lexmatch`

##### WARNING
`lexmatch` と `lexmatch?` は非推奨です。新しいコードでは [regex match expression]() を使ってください。この節は既存コードの参考のためだけに残しています。

`lexmatch` は `String` を正規表現パターンと照合し、マッチした部分を束縛できます。search モードのパターンは `(before, regex pieces, after)` で、`before` と `after` は未一致の前後部分に対する任意の束縛です。これらはカンマで区切られます。中央の regex 部分は空白のみで区切ります。regex 自体は文字列リテラルの列として書くので、複数行に分けたり、途中にコメントを挟んだりできます。`("b*" as b)` のように、マッチしたサブパターンに `as` で束縛することもできます。

`lexmatch?` は `is` に似た真偽チェックで、`is` 式と同じ文脈で使える束縛を導入できます。

古いコードでは、search モードの `lexmatch` は次のように書かれていました：

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

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

新しいコードでは、このような search モードのチェックは `=~` で書いてください。

`lexmatch` には lexer 風のモードもあります。`lexmatch <expr> with longest` は候補の中から最長一致を選びます（たとえば `if|[a-z]*` は longest モードでは `iff` を `iff` として一致させますが、first-match の search モードではまず `if` が一致します）。正規表現マッチ式はこの longest-match モードを提供しません。

正規表現リテラルでは `\\b` と `\\B` を正規表現構文の一部として使えますが、これらの単語境界アサーションは現在のところ `regex match expression` の定数コンテキストでは使えません。正規表現を一級の `Regex` 値として使う場合には動作し、この制限は将来緩和される予定です。また、正規表現リテラルは `\\d`、`\\D`、`\\s`、`\\S`、`\\w`、`\\W` もサポートしません。代わりに文字クラス内で `[[:digit:]]` のような POSIX 文字クラスを使ってください。

```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("")
  }
}
```

#### スプレッド演算子

MoonBit には、配列リテラル構文で `Array`、`String`、`Bytes` を構築するときに要素列を展開するためのスプレッド演算子があります。このような列を展開するには先頭に `..` を付ける必要があり、対応する要素型を返す `iter()` メソッドを持っていなければなりません。

たとえば、スプレッド演算子を使って配列を構築できます：

```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]")
}
```

同様に、スプレッド演算子を使って文字列を構築できます：

```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!")
}
```

最後の例は、スプレッド演算子で bytes 列を構築できることを示しています。

```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 構文

`todo` 構文（`...`）は、まだ実装されていないコードや将来の機能のプレースホルダを示すための特別な構文です。例えば：

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

<!-- path: language/methods.md -->
## メソッドとトレイト

### メソッドシステム

MoonBit のメソッドは、従来のオブジェクト指向言語とは異なる形でサポートされています。MoonBit のメソッドは、型コンストラクタに関連付けられたトップレベル関数にすぎません。メソッドを定義するには、関数名の前に `SelfTypeName::` を付けます。例えば `fn SelfTypeName::method_name(...)` のように書き、そのメソッドは `SelfTypeName` に属します。メソッド宣言のシグネチャ内では、`Self` を使って `SelfTypeName` を参照できます。

##### WARNING
現在は、メソッドを定義するための省略構文もあります。最初の引数名が `self` の場合、その関数宣言は `self` の型に対するメソッドとして扱われます。この構文は将来的に非推奨になる可能性があるため、新しいコードでは使わないことを推奨します。

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

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

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

メソッドを呼び出すには、修飾名 `T::method_name(..)` を使う方法と、`T` の型を最初の引数として受け取るドット構文を使う方法があります：

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

メソッドの最初の引数が、そのメソッドが属する型でもある場合、`x.method(...)` というドット構文で呼び出せます。MoonBit は `x` の型に基づいて正しいメソッドを自動的に見つけるため、型名やメソッドのパッケージ名まで書く必要はありません：

```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)
```

通常の関数と異なり、`TypeName::method_name` 構文で定義したメソッドはオーバーローディングをサポートします。各メソッドは別々の名前空間に存在するため、異なる型が同名のメソッドを定義できます：

```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()

}
```

#### ローカルメソッド

メソッド解決の単一ソースを保ち、曖昧さを避けるため、[メソッドはその型と同じパッケージでのみ定義できます](packages.md#trait-implementations) 。ただし例外が 1 つあります。MoonBit では、外部型に対する *private* メソッドをローカルに定義できます。これらのローカルメソッドは、その型自身のパッケージにあるメソッドを上書きできます（この場合、MoonBit は警告を出します）。また、上流 API を拡張・補完する用途に使えます：

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

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

#### 関数としてのエイリアスメソッド

MoonBit では、エイリアスを使ってメソッドを別名で呼び出せます。

メソッドエイリアスは、対応する名前のメソッドを作成します。対応する名前の関数を作ることもできます。可視性も制御できます。

```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())
}
```

### 演算子オーバーロード

MoonBit は、いくつかの組み込み trait を通じて、組み込み演算子の中置演算子をオーバーロードできます。例えば：

```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)
}
```

その他の演算子は、注釈付きメソッドを通じてオーバーロードされます。例えば `_[_]` や `_[_]=_` です：

```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
```

現在、次の演算子をオーバーロードできます：

| 演算子名              | オーバーロード機構             |
|-------------------|-----------------------|
| `+`               | trait `Add`           |
| `-`               | trait `Sub`           |
| `*`               | trait `Mul`           |
| `/`               | trait `Div`           |
| `%`               | trait `Mod`           |
| `==`              | trait `Eq`            |
| `<<`              | trait `Shl`           |
| `>>`              | trait `Shr`           |
| `-` (単項)          | trait `Neg`           |
| `_[_]` (要素取得)     | メソッド + エイリアス `_[_]`   |
| `_[_] = _` (要素設定) | メソッド + エイリアス `_[_]=_` |
| `_[_:_]` (ビュー)    | メソッド + エイリアス `_[_:_]` |
| `&`               | trait `BitAnd`        |
| `|`               | trait `BitOr`         |
| `^`               | trait `BitXOr`        |

`_[_]` / `_[_] = _` / `_[_:_]` をオーバーロードする場合、メソッドは正しいシグネチャを持つ必要があります：

- `_[_]` は `(Self, Index) -> Result` というシグネチャである必要があり、`let result = self[index]` として使われます
- `_[_]=_` は `(Self, Index, Value) -> Unit` というシグネチャである必要があり、`self[index] = value` として使われます
- `_[_:_]` は `(Self, start? : Index, end? : Index) -> Result` というシグネチャである必要があり、`let result = self[start:end]` として使われます

`_[_:_]` メソッドを実装すると、ユーザー定義型にビューを作れます。例えば次のようになります：

```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 システム

MoonBit は、オーバーロード / ad-hoc polymorphism のための trait システムを提供します。trait は、ある型が実装しなければならない操作の一覧を宣言します。trait は次のように定義できます：

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

trait 定義の本体では、特別な型 `Self` を使って、その trait を実装する型を参照します。

#### trait の拡張

trait は他の trait に依存できます。例えば：

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

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

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

#### trait の実装

trait を実装するには、`impl Trait for Type with method_name(...) { ... }` という構文を使って、trait が要求するすべてのメソッドを型が明示的に提供する必要があります。例えば：

```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) {
  ...
}
```

trait の `impl` では型注釈を省略できます。MoonBit は `Trait::method` のシグネチャと self 型に基づいて、型を自動的に推論します。

trait の作者は、一部のメソッドに対して **デフォルト実装** を定義することもできます。例えば：

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

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

実際のデフォルト実装 `impl J with f_twice` に加えて、`J` 内の `f_twice` の宣言にも `= _` を付ける必要がある点に注意してください。`= _` はこのメソッドにデフォルト実装があることを示す印で、どのメソッドにデフォルト実装があるかを一目で分かるようにし、可読性を高めます。

trait `J` の実装者は `f_twice` の実装を提供する必要はありません。`J` を実装するには `f` だけで十分です。必要であれば、明示的に `impl J for Type with f_twice` を書いてデフォルト実装を上書きすることもできます。

```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)
}

```

サブ trait を実装するには、super trait とサブ trait で定義されたメソッドを実装する必要があります。例えば：

```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)
}
```

すべてのメソッドにデフォルト実装がある trait でも、[abstract trait](packages.md#traits) などの機能をサポートするために、明示的に実装する必要があります。この目的のために、MoonBit は `impl Trait for Type`（つまりメソッド部分なし）の構文を提供します。`impl Trait for Type` は `Type` が `Trait` を実装していることを保証し、MoonBit は `Trait` 内のすべてのメソッドに対応する実装（独自実装またはデフォルト実装）があるかを自動で確認します。

すべてのメソッドにデフォルト実装がある trait を扱うだけでなく、`impl Trait for Type` はドキュメントとして、または実装前の TODO マークとしても使えます。

##### WARNING
現在、メソッドを持たない空の trait は自動的に実装されます。

#### trait の使用

ジェネリック関数を宣言するとき、型パラメータに実装すべき trait を注釈でき、制約付きジェネリック関数を定義できます。例えば：

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

`Eq` 制約がないと、`contains` 内の式 `x == elem` は型エラーになります。これで、関数 `contains` は `Eq` を実装する任意の型に対して呼び出せます。例えば：

```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 }))
}
```

##### trait メソッドを直接呼び出す

trait のメソッドは `Trait::method` で直接呼び出せます。MoonBit は `Self` の型を推論し、`Self` が本当に `Trait` を実装しているかを確認します。例えば：

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

trait 実装もドット構文で呼び出せますが、次の制約があります：

1. 通常のメソッドが存在する場合、ドット構文では常に通常のメソッドが優先されます
2. self 型のパッケージ内にある trait 実装だけを、ドット構文で呼び出せます
   - 複数の trait から同名のメソッドが利用可能な場合、曖昧性エラーが報告されます

上記の規則により、MoonBit のドット構文は柔軟でありながら良い性質を保てます。例えば、新しい依存関係を追加しても、曖昧性によって既存のドット構文コードが壊れることはありません。また、これらの規則によって MoonBit の名前解決は非常に単純になります。ドット構文で呼ばれるメソッドは、必ず現在のパッケージか型のパッケージ由来でなければなりません！

trait `impl` をドット構文で呼び出す例です：

```moonbit
struct MyCustomType {}

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

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

### trait オブジェクト

MoonBit は trait オブジェクトによる実行時多相をサポートしています。`t` が trait `I` を実装する型 `T` の値なら、`t as &I` を使って、`T` の `I` 実装メソッドを `t` と一緒に実行時オブジェクトへ詰め込めます。式の期待型が trait オブジェクト型だと分かっている場合は、`as &I` を省略できます。trait オブジェクトは値の具体的な型を消去するため、異なる具体型から作られたオブジェクトを同じデータ構造に入れて、統一的に扱えます：

```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?"]
    ),
  )
}
```

すべての trait がオブジェクト生成に使えるわけではありません。"object-safe" な trait のメソッドは、次の条件を満たす必要があります：

- `Self` はメソッドの最初の引数でなければなりません
- メソッドの型の中に `Self` は 1 回だけ現れなければなりません（つまり最初の引数のみ）

ユーザーは trait オブジェクトに対しても新しいメソッドを定義できます。struct や enum に新しいメソッドを定義するのと同じです：

```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(")")
}
```

### 組み込み trait

MoonBit は次のような便利な組み込み trait を提供します：

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

trait Compare : Eq {
  // `0` は等しい、`-1` は小さい、`1` は大きい
  compare(Self, Self) -> Int
}

trait Hash {
  hash_combine(Self, Hasher) -> Unit // 実装が必要
  hash(Self) -> Int // デフォルト実装あり
}

trait Show {
  output(Self, Logger) -> Unit // 実装が必要
  to_string(Self) -> String // デフォルト実装あり
}

trait Default {
  default() -> Self
}

```

#### 組み込み trait の導出

MoonBit は一部の組み込み trait について、実装を自動導出できます：

```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)
}
```

trait の導出について詳しくは [Deriving](derive.md) を参照してください。

<!-- path: language/derive.md -->
## trait の derive

MoonBit では、型定義からいくつかの組み込み trait を自動的に derive できます。

trait `T` を derive するには、その型で使われているすべてのフィールドが `T` を実装している必要があります。例えば、`struct A { x: T1; y: T2 }` に対して `Show` を derive するには、`T1: Show` と `T2: Show` の両方が必要です。

### Eq と Compare

`derive(Eq)` と `derive(Compare)` は、それぞれ等価性と比較のための対応するメソッドを生成します。フィールドは定義順に比較されます。enum では、ケース同士の順序は定義順になります。

```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)` は、その型に対する構造的なデバッグ実装を生成します。これはテストで `debug_inspect` と一緒に使ったり、診断メッセージを整形するときに `@debug.to_string` と一緒に使ったりできます。

```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 }")
}
```

列挙型も `Debug` を derive できます:

```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)` は、その型のデフォルト値を返すメソッドを生成します。

struct では、すべてのフィールドをデフォルト値にした struct がデフォルト値になります。

```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 })
}
```

enum では、パラメータを持たない唯一のケースがデフォルト値になります。

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

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

ケースがない enum や、パラメータなしケースが複数ある enum は `Default` を derive できません。

<!-- 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)` はその型の hash 実装を生成します。これにより、`HashMap` や `HashSet` など、`Hash` 実装を期待する場所でその型を使えるようになります。

```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)` は指定した型のランダム値を生成します。

### FromJson と ToJson

`derive(FromJson)` と `derive(ToJson)` は、型を JSON へ/から変換する往復可能なメソッド実装を自動的に derive します。主な用途はデバッグや、人間が読める形での保存です。

```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)
}
```

どちらの derive 指示子も、シリアライズとデシリアライズの具体的な振る舞いを設定するための複数の引数を受け取れます。

##### WARNING
JSON シリアライズ引数の実際の振る舞いは不安定です。

##### WARNING
JSON derive 引数は、生成される形式を大まかに制御するためのものです。型のレイアウトを厳密に制御したいなら、**代わりに 2 つの trait を直接実装することを検討してください**。

最近、多数の高度なレイアウト調整引数を非推奨にしました。そうした用途や今後それらを使う場合は、trait を手動実装してください。引数には `repr`、`case_repr`、`default`、`rename_all` などがあります。

```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 のスタイル

現在、enum のシリアライズには `legacy` と `flat` の 2 種類のスタイルがあり、`style` 引数でどちらかを選ぶ必要があります。次の enum 定義を考えます：

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

`derive(ToJson(style="legacy"))` では、enum は次のように出力されます：

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

`derive(ToJson(style="flat"))` では、enum は次のように出力されます：

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

##### `Option` の derive

例外として、組み込み型 `Option[T]` があります。本来なら `T | undefined` と解釈したいところですが、`Option[Option[T]]` に対して `Some(None)` と `None` を区別できなくなるという問題があります。

そのため、struct の直接フィールドである場合に限って `T | undefined` と解釈し、それ以外では `[T] | null` と解釈されます：

```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]]],
  })
}
```

#### コンテナ引数

- `rename_fields` と `rename_cases`（enum のみ）は、フィールド（enum と struct）および enum ケースを指定した形式へ一括でリネームします。利用できる形式は次のとおりです：
  - `lowercase`
  - `UPPERCASE`
  - `camelCase`
  - `PascalCase`
  - `snake_case`
  - `SCREAMING_SNAKE_CASE`
  - `kebab-case`
  - `SCREAMING-KEBAB-CASE`

  例：`my_long_field_name` というフィールドに対して `rename_fields = "PascalCase"` を指定すると、`MyLongFieldName` になります。

  リネームは、フィールド名が `snake_case`、struct/enum ケース名が `PascalCase` であることを前提にしています。
- `cases(...)`（enum のみ）は enum ケースのレイアウトを制御します。

  #### WARNING
  これは将来、case アトリビュートに置き換えられる可能性があります。

  例えば、次の enum では
  ```moonbit
  enum E {
    A(...)
    B(...)
  }
  ```

  `cases(A(...), B(...))` を使って各ケースを制御できます。

  詳細は以下の [Case arguments]() を参照してください。
- `fields(...)`（struct のみ）は struct フィールドのレイアウトを制御します。

  #### WARNING
  これは将来、field アトリビュートに置き換えられる可能性があります。

  例えば、次の struct では
  ```moonbit
  struct S {
    x: Int
    y: Int
  }
  ```

  `fields(x(...), y(...))` を使って各フィールドを制御できます。

  詳細は以下の [Field arguments]() を参照してください。

#### Case 引数

- `rename = "..."` はこの特定の case の名前を変更し、既存のコンテナ全体のリネーム指定があればそれを上書きします。
- `fields(...)` はこの case のペイロードのレイアウトを制御します。なお、位置引数フィールドのリネームは現在できません。

  詳細は以下の [Field arguments]() を参照してください。

#### Field 引数

- `rename = "..."` はこの特定の field の名前を変更し、既存のコンテナ全体のリネーム指定があればそれを上書きします。

<!-- path: language/error-handling.md -->
## エラーハンドリング

エラーハンドリングは、私たちの言語設計の中核です。以下では、MoonBit でのエラーハンドリングの方法を説明します。MoonBit の基本的な知識があることを前提としています。まだの場合は [A tour of MoonBit](../tutorial/tour.md) を参照してください。

### エラー型

MoonBit では、すべてのエラー値を汎用エラー型である `Error` 型で表現できます。

ただし、`Error` は直接構築できません。次の形式で具体的なエラー型を定義する必要があります：

```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
古い `suberror A B` 構文は非推奨です。代わりに `suberror A { A(B) }` を使ってください。

これらのエラー型は自動的に `Error` 型へ昇格でき、パターンマッチで取り出せます：

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

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

`Error` 型には複数のエラー型を含められるため、`Error` 型に対するパターンマッチでは、すべてのエラー型に対応するためにワイルドカード `_` を使う必要があります。例えば：

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

`Error` は、具体的なエラー型が不要な場面や、あらゆる種類のサブエラーを一括で扱いたい場面で使うことを想定しています。

#### Failure

組み込みエラー型として `Failure` があります。

便利な `fail` 関数もあります。これはエラーとソース位置の両方を表示するための定義済み出力テンプレートを持つ、実質的にはコンストラクタです。実際には `Failure` より `fail` を常に優先して使います。

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

### エラーの送出

`raise` キーワードは、関数の実行を中断してエラーを返すために使います。

関数の型宣言では、`raise` とエラー型を組み合わせて、その関数が実行中にエラーを送出する可能性があることを示せます。例えば次の `div` 関数は `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
}
```

具体的なエラー型が重要でない場合は `Error` を使えます。便宜上、`raise` の後のエラー型は省略でき、その場合は `Error` 型を使うことを意味します。例えば次の関数シグネチャは等価です：

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

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

エラー型に対してジェネリックな関数では、`Error` 制約を使えます。例えば：

```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
  }
}
```

エラーを送出しない関数には、シグネチャに `noraise` を追加できます。例えば：

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

#### エラー多相性

これは、高階関数が別の関数を引数として受け取るときに起こります。引数として渡される関数がエラーを送出する場合もしない場合もあり、それによってこの関数自身の振る舞いが変わります。

代表的な例は `Array` の `map` です：

```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
}
```

ただしこのように書くと、`map` 関数が常にエラーを送出する可能性を持つことになり、実態に合いません。

そこでエラー多相性が導入されています。`raise?` を使うと、エラーを送出する場合もしない場合もあることを表せます。

```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)
}
```

`map_with_polymorphism` のシグネチャは、実際に渡される引数によって決定されます。

### エラー処理

関数を通常どおり呼び出すと、エラーが発生した場合はそのまま再送出されます。例えば：

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

ただし、エラーをその場で処理したい場合もあります。

#### Try ... Catch

`try` と `catch` を使ってエラーを捕捉し、処理できます。例えば：

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

```default
division by zero
```

ここでは、`try` でエラーを送出する可能性がある関数を呼び出し、`catch` で捕捉したエラーをパターンマッチして処理しています。エラーが発生しなかった場合、`catch` ブロックは実行されず、代わりに `noraise` ブロックが実行されます。

エラーが発生しなかったときに何もしないなら、`noraise` ブロックは省略できます。例えば：

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

`try` の本体が単純な式である場合は、中括弧、さらには `try` キーワード自体も省略できます。例えば：

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

#### Result への変換

潜在的なエラーを捕捉し、[`Result`](fundamentals.md#option-and-result) 型の first-class な値へ変換することもできます：

```moonbit
test {
  let res : Result[Int, DivError] = Ok(div(6, 0) * div(6, 3)) catch {
    error => Err(error)
  }
  match res {
    Err(DivError(message)) => @test.assert_eq(message, "division by zero")
    Ok(_) => fail("expected division to fail")
  }
}
```

#### エラー時にパニックする

予期しないエラーが起きたときに直接パニックさせることもできます：

```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
}
```

#### エラー推論

`try` ブロック内では、複数種類のエラーが送出されることがあります。その場合、コンパイラは共通エラー型として `Error` 型を使います。したがってハンドラ側では、すべてのエラーを捕捉するためにワイルドカード `_` を使い、`e => raise e` で他のエラーを再送出する必要があります。例えば：

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

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

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

<!-- path: language/packages.md -->
## パッケージでプロジェクトを管理する

大規模なプロジェクトを開発するとき、プロジェクトは通常、相互に依存する小さなモジュール単位に分割する必要があります。さらに多くの場合、他人の成果物を利用します。代表的なものが、MoonBit の標準ライブラリである [core](https://github.com/moonbitlang/core) です。

### パッケージとモジュール

MoonBit では、コード整理の最も重要な単位はパッケージです。パッケージは複数のソースコードファイルと 1 つのパッケージ設定ファイル（`moon.pkg`、または旧形式の `moon.pkg.json`）から構成されます。パッケージは、`main` 関数を含む `main` パッケージにも、[`is-main`](../toolchain/moon/package.md#is-main) フィールドで識別されるライブラリ用パッケージにもなれます。

モジュールに対応するプロジェクトは、複数のパッケージと 1 つの `moon.mod.json` 設定ファイルから構成されます。

モジュールは [`name`](../toolchain/moon/module.md#source-directory) フィールドで識別され、通常は `/` で区切られた 2 つの部分、つまり `user-name/project-name` から構成されます。パッケージは、[`source`](../toolchain/moon/module.md#source-directory) フィールドで定義されるソースルートからの相対パスで識別されます。完全な識別子は `user-name/project-name/path-to-pkg` になります。

別のパッケージのものを使う場合、まずモジュール間の依存関係を `moon.mod.json` の [`deps`](../toolchain/moon/module.md#dependency-management) フィールドで宣言する必要があります。その後、パッケージ間の依存関係をパッケージファイル（`moon.pkg`、または旧形式の `moon.pkg.json`）の [`import`](../toolchain/moon/package.md#import) フィールドで宣言します。多くの core パッケージも同じ規則に従います。`@json`、`@test`、その他の通常の core エイリアスを使う場合は、`core_package_not_imported` 警告を避けるために、対応する `moonbitlang/core/...` パッケージを `import` に追加してください。

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

パッケージの **デフォルトエイリアス** は、識別子を `/` で分割した最後の部分です。`@pkg_alias` を使うと import した要素にアクセスできます。ここで `pkg_alias` は完全な識別子でもデフォルトエイリアスでも構いません。カスタムエイリアスは、[`import`](../toolchain/moon/package.md#import) フィールドで定義できます。

`moon.pkg` では、カスタムエイリアスは次のように書きます：

```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 と組み込み名

`@pkg.` を省略すると、MoonBit は現在のパッケージと prelude の中で修飾されていない名前を解決します。そのため、同じ名前のローカル定義があると prelude の定義は隠されます。

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

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

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

`prelude` は特別なパッケージです。デフォルトで利用でき、そこで公開された名前は明示的な `import` なしで通常の未修飾名解決に参加します。

コンパイラ組み込み要素は別のカテゴリです。`Int` などの型はどのパッケージからも import されるのではなく、言語そのものに組み込まれているため、`@builtin.Int` は存在しません。同じ区別は `String`、`Bool`、`Unit` などのコンパイラ既知の名前にも当てはまります。

#### 内部パッケージ

特定のパッケージからのみ利用できる内部パッケージを定義できます。

`a/b/c/internal/x/y/z` 内のコードは、`a/b/c` と `a/b/c/**` のパッケージからのみ利用できます。

#### using

`using` 構文を使うと、別のパッケージで定義されたシンボルを import できます。

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

`pub` 修飾子を付けると、再 export と見なされます。

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

### アクセス制御

MoonBit には、どのコード部分が他のパッケージからアクセス可能かを管理する包括的なアクセス制御システムがあります。この仕組みは、カプセル化、情報隠蔽、明確な API 境界の維持に役立ちます。可視性修飾子は関数、変数、型、trait に適用でき、他者がどのようにコードを利用できるかを細かく制御できます。

#### 関数

デフォルトでは、すべての関数定義と変数束縛は他のパッケージからは  *見えません*。トップレベルの `let`/`fn` の前に `pub` 修飾子を付けると公開できます。

#### エイリアス

デフォルトでは、[function alias](fundamentals.md#type-alias) と [method alias](methods.md#alias-methods-as-functions) は元の定義の可視性に従います。一方で、[type alias](fundamentals.md#type-alias) と [using]() は他のパッケージからは  *見えません*。

定義の前に `pub` 修飾子を付けるか、annotation 内の `visibility` フィールドに値を入れることができます。

#### 型

MoonBit の型には 4 種類の可視性があります：

- Private 型：`priv` で宣言され、外部から完全に見えません
- Abstract 型：型のデフォルト可視性です。

  Abstract 型では名前だけが外部に見え、型の内部表現は隠されます。Abstract 型を デフォルトにしているのは、カプセル化と情報隠蔽を促すための設計上の選択です。
- `pub` で宣言される readonly 型です。

  readonly 型の内部表現は外部から見えますが、外部からできるのは値の読み取りだけです。構築と変更はできません。
- `pub(all)` で宣言される完全公開型です。

  外部からこれらの型を自由に構築し、値を読み取り、可能であれば変更できます。

型自体の可視性に加えて、public な `struct` のフィールドに `priv` を付けると、そのフィールドを外部から完全に隠せます。private フィールドを持つ `struct` は外部から直接構築できませんが、関数的な struct 更新構文を使って public フィールドは更新できます。

readonly 型は、OCaml の [private types](https://ocaml.org/manual/5.3/privatetypes.html) に触発された非常に便利な機能です。要するに、`pub` 型の値は パターンマッチやドット構文で分解できますが、他のパッケージでは構築や変更は できません。

##### NOTE
`pub` 型が定義された同じパッケージ内では制限はありません。

<!-- 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!
}
```

MoonBit のアクセス制御は、`pub` 型・関数・変数を private 型を使って定義してはならない、という原則に従います。private 型は `pub` な要素が使われるすべての場所で利用できるとは限らないためです。MoonBit には、この原則に反する使い方を防ぐための整合性チェックが組み込まれています。

<!-- 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`!
```

#### trait

trait にも `struct` や `enum` と同様に 4 種類の可視性があります。private、abstract、readonly、fully public です。

- Private trait は `priv trait` で宣言され、外部からは完全に見えません。
- Abstract trait はデフォルトの可視性です。trait 名だけが外部に見え、trait 内のメソッドは公開されません。
- Readonly trait は `pub trait` で宣言され、メソッドは外部から呼び出せますが、readonly trait に新しい実装を追加できるのは現在のパッケージだけです。
- Fully public trait は `pub(open) trait` で宣言され、現在のパッケージ外からも新しい実装を追加でき、メソッドを自由に使えます。

Abstract trait と readonly trait は sealed です。trait を定義したパッケージだけがそれらを実装できるからです。sealed な（abstract または readonly の）trait をそのパッケージ外で実装するとコンパイラエラーになります。

##### trait 実装

実装は関数と同様に独立した可視性を持ちます。実装が `pub` でない限り、その型は現在のパッケージ外では trait を満たしているとは見なされません。

trait システムの整合性（つまり、すべての `Type: Trait` の組に対して世界で一意の実装があること）を保ち、サードパーティ製パッケージが既存プログラムの挙動を誤って変更するのを防ぐため、MoonBit では型に対するメソッド定義や trait 実装に次の制限を設けています：

-  *型を定義したパッケージだけが、その型のメソッドを定義できます*。したがって、組み込み型や外部型に対して新しいメソッドを定義したり、既存メソッドを上書きしたりはできません。
  - この規則には例外があります。[local methods](methods.md#local-method) です。ただしローカルメソッドは常に private なので、MoonBit の型システムの整合性を壊しません。
-  *実装を定義できるのは、その型のパッケージか trait のパッケージだけです*。例えば、`impl @pkg1.Trait for @pkg2.Type` を書けるのは `@pkg1` と `@pkg2` だけです。

上記 2 つ目の規則により、新しい trait を定義して実装することで外部型に新しい機能を追加できます。これにより、MoonBit の trait とメソッドの仕組みは整合性を保ちながら柔軟になります。

##### WARNING
現在、空の trait は自動的に実装されます。

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 }
```

このパッケージの外からは、ユーザーは次のものだけを見られます：

```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
```

`Number` の作者は、`Number` を実装できるのが `Int` と `Double` だけであるという事実を利用できます。外部では新しい実装を追加できないからです。

### 仮想パッケージ

##### WARNING
仮想パッケージは実験的機能です。バグや未定義の動作が含まれている可能性があります。

インターフェースとして機能する仮想パッケージを定義できます。仮想パッケージはビルド時に特定の実装へ置き換えられます。現在、仮想パッケージには通常の関数しか含められません。

仮想パッケージは、コードを変更せずに異なる実装を切り替えたいときに便利です。

#### 仮想パッケージの定義

仮想パッケージであることを宣言し、そのインターフェースを MoonBit の interface ファイルに定義する必要があります。

`moon.pkg` には、[`virtual`](../toolchain/moon/package.md#declarations) フィールドを追加する必要があります：

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

`has-default` は、その仮想パッケージにデフォルト実装があるかどうかを示します。

パッケージ内には、interface ファイル `pkg.mbti` を追加する必要があります：

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

fn log(String) -> Unit
```

interface ファイルの 1 行目は `package "full-package-name"` である必要があります。続いて宣言を書きます。[アクセス制御]() の `pub` キーワードと、関数のパラメータ名は省略してください。

#### 仮想パッケージの実装

仮想パッケージにはデフォルト実装を持たせることができます。[`virtual.has-default`](../toolchain/moon/package.md#declarations) を `true` にすると、同じパッケージ内で通常どおりコードを実装できます。

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

仮想パッケージはサードパーティによって実装することもできます。[`implements`](../toolchain/moon/package.md#implementations) に対象パッケージの完全名を指定すると、未実装や不一致の実装についてコンパイラが警告してくれます。

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

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

#### 仮想パッケージの利用

仮想パッケージを使う方法は他のパッケージと同じです。使いたいパッケージに [`import`](../toolchain/moon/package.md#import) フィールドを定義してください。

#### 仮想パッケージの上書き

仮想パッケージにデフォルト実装があり、それを使うのであれば、追加設定は不要です。

それ以外の場合は、使いたい実装の配列を指定して、[`overrides`](../toolchain/moon/package.md#overriding-implementations) フィールドを定義できます。

```text
import {
  "moonbit-community/language/packages/virtual",
}

options(
  "is-main": true,
  overrides: [ "moonbit-community/language/packages/implement" ],
)
```

要素を使うときは、仮想パッケージを参照してください。

```moonbit
///|
fn main {
  @virtual.log("Hello")
}
```

<!-- path: language/tests.md -->
## テストの書き方

テストは、プログラムの品質と保守性を高めるうえで重要です。プログラムの振る舞いを検証し、時間が経っても回帰を防ぐための仕様としても機能します。

MoonBit にはテスト機能があり、テストを書く作業をより簡単にできます。

### テストブロック

MoonBit には、インラインのテストケースを書くための test コードブロックがあります。例えば：

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

test コードブロックは、本質的には `Unit` を返す関数ですが、[`Error`](error-handling.md#error-types)、つまり戻り値型の位置では `Unit!Error` と表示されるエラーを送出する可能性があります。これは `moon test` の実行中に呼び出され、ビルドシステムを通じてテストレポートを出力します。`assert_eq` 関数は標準ライブラリ由来で、アサーションが失敗するとエラーメッセージを表示してテストを終了します。文字列 `"test_name"` はテストケースを識別するために使われますが、省略可能です。

テスト名が `"panic"` で始まる場合、そのテストの期待動作は panic を発生させることであり、panic が発生した場合にのみテストが成功します。例えば：

```moonbit
test "panic_test" {
  let _ : Int = Option::None.unwrap()
}
```

### スナップショットテスト

期待値を細かく指定しながらテストを書くのは面倒なことがあります。そのため MoonBit には 3 種類のスナップショットテストがあります。いずれも `moon test --update` で自動的に挿入または更新できます。

#### `Show` のスナップショット

`Show` トレイトを実装しているものなら、`inspect(x, content="x")` を使って検査できます。前述のとおり、`Show` は導出可能な組み込みトレイトであり、データ構造の内容を表示する `to_string` を提供します。ラベル付き引数 `content` は、`moon test --update` が自動で挿入するため省略できます：

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

test "show snapshot test" {
  debug_inspect({ x: 10 }, content="{ x: 10 }")
}
```

#### `JSON` のスナップショット

導出された `Show` トレイトの問題は、整形出力をしないため、出力が非常に長くなることです。

解決策は `@json.inspect(x, content=x)` を使うことです。これにより、出力は JSON 構造になり、整形後に読みやすくなります。

```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"],
    ],
  ])
}
```

必要な情報だけを残すために、独自の `ToJson` を実装することもできます。

#### あらゆるもののスナップショット

それでも、1 つのデータ構造だけでなく、処理全体の出力を記録したいことがあります。

完全なスナップショットテストでは、`@test.T::write` と `@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")
}
```

これにより、そのパッケージの `__snapshot__` 以下に、指定したファイル名のファイルが作成されます：

```default
Hello, world! And hello, MoonBit!
```

これは、画像や動画、あるいは独自データの生成など、アプリケーションの生成出力をテストするためにも使えます。

`@test.T::snapshot` は常に例外を送出するため、テストブロックの最後で使う必要がある点に注意してください。

### ブラックボックステストとホワイトボックステスト

ライブラリを開発するときは、利用者が正しく使えるかを確認することが重要です。例えば、型や関数を public にし忘れることがあります。そのため MoonBit には BlackBox テストがあり、開発者が利用者の立場を把握しやすくしています。

- パッケージ内のすべてのメンバーにアクセスできるテストは、すべてが見えるため WhiteBox テストと呼ばれます。この種のテストは、インラインで定義することも、名前が `_wbtest.mbt` で終わるファイルに定義することもできます。
- パッケージの public メンバーのみにアクセスできるテストは、BlackBox テストと呼ばれます。この種のテストは、名前が `_test.mbt` で終わるファイルに定義する必要があります。

WhiteBox テストファイル（`_wbtest.mbt`）は、パッケージ設定（`moon.pkg`、または旧形式の `moon.pkg.json`）の `import` および `wbtest-import` セクションで定義されたパッケージを import します。

BlackBox テストファイル（`_test.mbt`）は、現在のパッケージと、パッケージ設定（`moon.pkg`、または旧形式の `moon.pkg.json`）の `import` および `test-import` セクションで定義されたパッケージを import します。

<!-- path: language/benchmarks.md -->
## ベンチマークの書き方

ベンチマークは、コードの性能を測定する手段です。異なる実装を比較したり、時間の経過に伴う性能変化を追跡したりするために使えます。

### test ブロックによるベンチマーク

関数をベンチマークする最も簡単な方法は、`@bench.T` 引数付きの test ブロックを使うことです。`@bench.T::bench` メソッドは `() -> Unit` 型の関数を受け取り、適切な回数だけ実行します。計測と統計解析は自動で行われ、`moon` に渡されてコンソール出力に表示されます。

```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)) })
}
```

出力は次のとおりです：

```default
time (mean ± σ)         range (min … max) 
  21.67 µs ±   0.54 µs    21.28 µs …  23.14 µs  in 10 ×   4619 runs
```

関数は `10 × 4619` 回実行されます。2 つ目の数値はベンチマークユーティリティによって自動的に決定されます。これは、正確な計測のために十分長い時間になるまで反復回数を増やしていくためです。1 つ目の数値は、`@bench.T::bench` 引数に名前付き引数 `count` を渡すことで調整できます。

```moonbit
test (b : @bench.T) {
  b.bench(fn() { b.keep(fib(20)) }, count=20)
}
```

`@bench.T::keep` は重要な補助関数で、計算が最適化されて丸ごと省略されるのを防ぎます。純粋関数をベンチマークする場合は、最適化の影響を避けるために必ずこの関数を使ってください。ただし、コンパイラが事前計算して定数に置き換える可能性は依然としてあります。

### まとめてベンチマークする

ベンチマークのよくある用途は、同じ関数の 2 つ以上の実装を比較することです。この場合、比較しやすいように、ブロック内でまとめてベンチマークするとよいでしょう。`@bench.T::bench` メソッドの `name` 引数は、各ベンチマークを識別するために使えます。

```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)) })
}
```

これで、出力を見ればどちらが速いか判断できます：

```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
```

### 生のベンチマーク統計

さらに分析するために、生のベンチマーク統計を取得したい場合があります。`@bench.single_bench` 関数は抽象型 `Summary` を返し、JSON 形式にシリアライズできます。`Summary` 型の安定性は保証されていません。

この場合、計算が最適化で消されないように注意する必要があります。`keep` 関数を単独の関数として使うことはできません。これは `@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))
}
```

出力は次のようになるかもしれません：

```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
}
```

時間の単位はマイクロ秒です。

<!-- path: language/docs.md -->
## コメントとドキュメント

### コメント

コード内の通常のコメントには `//` を使います：

```moonbit
// Explain why this branch exists.
let retries = 3
```

トップレベルブロックの先頭で `///|` をよく見かけることもあります。これは トップレベル項目を明示的に区切るための空のドキュメントコメント行です。これは現時点のドキュメントツールにとって重要であり、将来のキャッシュやその他のツール用途に向けても、トップレベルブロックの境界を明確に保ちます。実際には、`///|` は通常の MoonBit コードでもドキュメントソースでも役立ちます。

### ドキュメントコメント

ドキュメントコメントは、`fn`、`let`、`enum`、`struct`、`type` などのトップレベル項目の直前の各行に `///` を使って書きます。ドキュメントコメントは Markdown で記述します。

```moonbit
/// Return a new array with reversed elements.
fn[T] reverse(xs : Array[T]) -> Array[T] {
  ...
}
```

`mbt check` とマークされたドキュメントコメント内の Markdown コードブロックは、ドキュメントテストとして扱われます。`moon check` と `moon test` はこれらのテストを自動的に検査・実行するため、ドキュメントコメント内の例を常に最新に保てます。テストブロックにしたい場合は、スニペットを `test { .. }` で囲んでください：

```moonbit
/// Increment an integer by one,
///
/// Example:
/// ```mbt check
/// test {
///   inspect(incr(41), content="42")
/// }
/// ```
pub fn incr(x : Int) -> Int {
  x + 1
}
```

コードスニペットをドキュメントテストとして扱わせたくない場合は、Markdown コードブロックに `mbt check` 以外の言語 ID を付けてください：

```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
}
```

現在、ドキュメントテストは常に [ブラックボックステスト](tests.md#blackbox-tests-and-whitebox-tests) として扱われます。そのため、private な定義にはドキュメントテストを付けられません。

### リテラテ `.mbt.md` ファイル

MoonBit は `.mbt.md` で終わるリテラテ Markdown ファイルもサポートします。これらのファイルは、パッケージ内で検査済みドキュメントとして置くことも、`moon check` と `moon test` の単独ファイル入力として使うこともできます。

単独ファイルの場合は、次を実行します：

```bash
moon check README.mbt.md
moon test README.mbt.md
```

プロジェクト内では、引き続きパッケージ単位の `moon check` と `moon test` コマンドを使ってください。

コードフェンスの言語によって、各ブロックの扱いが決まります：

- `mbt`: コンパイルされるが、テストエントリは作成しない MoonBit コード
- `mbt check`: MoonBit のドキュメントテストコード。アサーションを使いたいときは、ブロック内で `test { .. }` または `async test` を使います。
- `mbt nocheck`: コンパイルもテストもしない MoonBit コードを表示する
- `moonbit`: ドキュメント用の通常の表示コードブロック。コンパイルもテストもされません。

例えば：

```markdown
```mbt nocheck
///|
fn helper() -> Int {
  42
}
```

```mbt check
///|
test "forty two" {
  inspect(40 + 2, content="42")
}
```

```mbt nocheck
///|
fn native_only() -> Unit {
  ...
}
```
```

単独の `.mbt.md` ファイルでは、front matter を使って import や対象バックエンドを指定することもできます：

```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")
}
```
```

ファイルが直接 import できるパッケージを明示したい場合は `moonbit.import` を使います。モジュール依存関係だけを宣言して、Moon に import を自動生成させたい場合は `moonbit.deps` を使います。

<!-- path: language/attributes.md -->
## アトリビュート

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.

アトリビュートの構文は次のとおりです：

```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 ')'
```

アトリビュートには 2 種類あります。組み込みアトリビュートとユーザー定義アトリビュートです。例えば：

```default
##deprecated("message")
##custom.attribute(key="value", flag=true)
```

最初のアトリビュートは組み込みアトリビュートです。アトリビュート名に名前空間プレフィックスはありません。組み込みアトリビュートは MoonBit コンパイラに認識され、特定の意味を持ちます。

2 つ目のアトリビュートはユーザー定義アトリビュートです。アトリビュート名に `custom.` という名前空間プレフィックスがあります。ユーザー定義アトリビュートはコンパイラには無視されますが、外部ツールはソースコードを解析して利用できます。

##### NOTE
MoonBit はランタイムリフレクションをサポートしない設計です。これは悪用されやすく、ツールチェーン（たとえばコンパイラ）がコンパイル時にエラーを検出できなくなり、コードの保守性が下がります。また、性能最適化にも悪影響があります。

私たちはコンパイル時コード生成を使うことを好みます。これにより静的型付けと性能の利点を保てます（ただし、不要な複雑さを避けるため慎重に使うべきです）。

### 非推奨アトリビュート

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
}
```

`#deprecated` アトリビュートは次の文脈で使えます：

- トップレベルの値宣言（`fn`、`let`、`const` を含む）
- トップレベルの型宣言（`type`、`struct`、`enum` を含む）
- trait メソッド宣言
- trait のデフォルト実装

一般的な形式は次のとおりです：

- `#deprecated`

  項目を非推奨にし、デフォルトの警告メッセージを使います。
- `#deprecated("Use new_function instead")`

  項目を非推奨にし、カスタム警告メッセージを使います。非推奨 API が使われるたびに、指定したメッセージが警告として表示されます。
- `#deprecated("Use new_function instead", skip_current_package=true)`

  項目を非推奨にし、カスタム警告メッセージを使いますが、同じパッケージ内で非推奨 API が使われた場合は警告を出しません。
- `#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

`#alert` アトリビュートは API にカテゴリとメッセージを付与します。その API が使われると、MoonBit は alert 警告を出します。

```moonbit
##alert(unsafe, "This function is unsafe.")
fn[A] alert_unsafe_get(arr : Array[A], index : Int) -> A {
  arr[index]
}
```

第 1 引数は alert のカテゴリで、第 2 引数はユーザーに表示されるメッセージです。この警告は `alert` や `alert_unsafe` などの警告名で設定できます。

For more detail, see [alert warning](../toolchain/moon/package.md#alert-warning).

### エイリアスアトリビュート

`alias` アトリビュートは、添字に関係する演算子をオーバーロードしたり、トップレベル関数や変数に別名を付けたりするために使います。形式は 2 種類あります：

- `#alias("op")`。ここで `op` は次の添字演算子を表す文字列のいずれかです：
  - `_[_]`: 添字演算子
  - `_[_]=_`: 添字代入演算子
  - `_[_:_]`: as view 演算子
- `#alias(id)`。ここで `id` は別名を表す識別子です。

どちらの形式でも追加引数を指定できます：

- `visibility="modifier"`

  ラベル付き引数で、別名の可視性を変更します。`modifier` は `pub` または `priv` です。指定しない場合、別名の可視性は元の関数または変数と同じになります。
- `deprecated` または `deprecated="message"`

  別名を非推奨としてマークします。メッセージを指定した場合、別名が使われると警告として表示されます。

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` アトリビュート

The `#label_migration` attribute is used to help you safely evolve your API
by warning users during the transition period.

形式は次の 3 種類です：

- `#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.

  `msg` 引数は、移行に関する追加情報を提供する文字列です。
  ```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.

  `msg` 引数は、移行に関する追加情報を提供する文字列です。
  ```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.

  `msg` 引数は、移行に関する追加情報を提供する文字列です。
  ```moonbit
  #label_migration(x, alias=xx)
  #label_migration(x, alias=y, msg="warning")
  fn label_migration_alias(x~ : Int) -> Int {
    x
  }
  ```

### 可視性アトリビュート

##### NOTE
このトピックではアクセス制御は扱いません。`pub`、`pub(all)`、`priv` について詳しくは [Access Control](packages.md#access-control) を参照してください。

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.

- `change_to` 引数は、型の新しい可視性を表す文字列です。値は `"abstract"` または `"readonly"` のどちらかです。

  | `change_to`   | 無効になる使い方                                                        |
  |---------------|-----------------------------------------------------------------|
  | `"readonly"`  | 型のインスタンスを生成すること、またはそのフィールドを変更すること。                              |
  | `"abstract"`  | 型のインスタンスを生成すること、インスタンスのフィールドを変更すること、パターンマッチ、またはラベルによるフィールドアクセス。 |
- The optional `message` argument is a string that provides additional information about the visibility change.

### 内部アトリビュート

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

`#doc(hidden)` アトリビュートは生成されるドキュメントから API を隠します。

```moonbit
##doc(hidden)
pub fn hidden_helper() -> Unit {
  ()
}
```

コードからは利用可能なままにする必要がある一方で、ドキュメント化された API としては表示したくない公開宣言に使います。

### 警告アトリビュート

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
}
```

プレフィックスの意味は次のとおりです：

- `+warning_name`: 警告を有効化
- `-warning_name`: 警告を無効化
- `@warning_name`: 有効な警告をエラーとして扱う

現在、このアトリビュートは一部の特定の警告にのみ対応しています。

To learn more about warning names, see [warning list](../toolchain/moon/package.md#warnings-list).

### Must Implement One アトリビュート

`#must_implement_one` アトリビュートは trait に付けて、各実装がデフォルトメソッド実装だけに依存せず、少なくとも 1 つのメソッドを明示的に定義することを要求します。

引数を指定しない場合、その trait の少なくとも 1 つのメソッドを明示的に実装する必要があります：

```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(_) {}
```

メソッド名を指定した場合、列挙されたメソッドのうち少なくとも 1 つを明示的に実装する必要があります：

```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(_) {}
```

同じ trait に複数の `#must_implement_one` アトリビュートを付けることで、複数のメソッドグループから明示的な実装を要求できます。

### Inline Attribute

`#inline` アトリビュートは関数に対する最適化ヒントです。可能であればその関数をインライン化するようコンパイラに依頼します：

```moonbit
##inline
fn add_one(x : Int) -> Int {
  x + 1
}
```

`#inline(never)` を使うと、関数をインライン化しないようコンパイラに依頼できます：

```moonbit
##inline(never)
fn keep_stack_frame(x : Int) -> Int {
  x + 1
}
```

これらのアトリビュートはヒントです。関数のソースレベルの振る舞いは変わりません。

### 外部アトリビュート

`#external` アトリビュートは、抽象型を外部型としてマークするために使います。

- Wasm および Wasm GC バックエンドでは、これは `externref` と解釈されます。
- JavaScript バックエンドでは、これは `any` と解釈されます。
- ネイティブバックエンドでは、これは `void*` と解釈されます。

```moonbit
##external
type AttrPtr
```

### Borrow/Owned アトリビュート

`#borrow` と `#owned` アトリビュートは FFI 宣言で使い、参照カウントされる MoonBit 引数を外部コードへどのように渡すかを記述します。これは `Bytes`、`String`、`FixedArray[T]`、抽象型などのボックス化された MoonBit 値で重要です。これらの値のライフタイムは C および Wasm バックエンドで参照カウントにより管理されます。

外部関数が呼び出し中に `param` を読むだけで、それを保存したり返したりしない場合は `#borrow(param)` を使います。borrow された引数の所有権は MoonBit に残るため、外部関数はその引数に対して `moonbit_decref` や `$moonbit.decref` を呼ぶ必要がありません。

外部関数が `param` の所有権を受け取る場合、たとえば保存して後で解放する場合は `#owned(param)` を使います。owned 引数は不要になった時点で、最終的に外部側が解放する必要があります。

```moonbit
##borrow(filename)
extern "C" fn open(filename : Bytes, flags : Int) -> Int = "open"
```

完全な呼び出し規約のルールについては [FFI ライフタイム管理](ffi.md#the-borrow-and-owned-attribute) を参照してください。

### `as_free_fn` アトリビュート

`#as_free_fn` アトリビュートは、メソッドを free 関数としても宣言することを示すために使います。free 関数の可視性や名前を変更したり、別個の非推奨警告を与えたりすることもできます。

```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 アトリビュート

`#callsite` アトリビュートは、呼び出し元で起こる属性を示すために使います。

`autofill` を指定でき、呼び出し元で引数 [SourceLoc と ArgLoc](fundamentals.md#autofill-arguments) を自動補完します。

### Skip アトリビュート

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

`#coverage.skip` アトリビュートは関数内のカバレッジ操作をスキップします。

```moonbit
##coverage.skip
fn platform_specific_helper() -> Unit {
  ()
}
```

プラットフォーム固有のフォールバックコードや、意図的にカバレッジ測定から除外するコードパスなど、カバレッジレポートに影響させたくない関数に使います。詳しくは [Skipping coverage](../toolchain/moon/coverage.md#skipping-coverage) を参照してください。

### 設定アトリビュート

`#cfg` アトリビュートは条件付きコンパイルを行うために使います。例は次のとおりです：

<!-- 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` アトリビュートは、JavaScript バックエンド向けのモジュール依存を宣言するために使います。

`cjs` 形式では `require` として解釈され、`esm` 形式では `import` として解釈されます。

<!-- MANUAL CHECK -->
```moonbit
##module("math-utils")
pub extern "js" fn add_from_module(x : Int, y : Int) -> Int = "add"
```

<!-- path: language/ffi.md -->
## 外部関数インターフェース (FFI)

ここまでで紹介してきたのは、純粋な計算を記述する方法でした。実際には、現実世界とやり取りする必要があります。ただし、その「世界」はバックエンドごとに異なり（C、JS、Wasm、WasmGC）、ランタイム（[Wasmtime](https://wasmtime.dev/)、Deno、Browser など）に基づくこともあります。

### バックエンド

MoonBit には現在 5 つのバックエンドがあります：

- Wasm
- Wasm GC
- JavaScript
- C
- LLVM（実験的）

#### Wasm

ここでいう Wasm は、MVP 以降のいくつかの提案を含む WebAssembly を指します。

- bulk-memory-operations
- multi-value
- reference-types

互換性を高めるため、`init` 関数は [`start` 関数](https://webassembly.github.io/spec/core/syntax/modules.html#start-function) としてコンパイルされ、`main` 関数は `_start` としてエクスポートされます。

##### NOTE
Wasm バックエンドでは、外部世界とやり取りする関数はすべてホストに依存します。例えば、Wasm と Wasm GC バックエンドの `println` は、呼び出しごとに UTF-16 コードユニットを 1 つ出力する `spectest.print_char` という関数のインポートに依存します。標準ライブラリの `env` パッケージや `moonbitlang/x` の一部のパッケージは、MoonBit ランタイム用に定義された特定のホスト関数に依存します。生成した Wasm の移植性を高めたいなら、これらは使わないでください。

#### Wasm GC

ここでいう Wasm GC は、Garbage Collection 提案を備えた WebAssembly を指し、`struct` や `array` などの参照型でデータ構造を表現し、線形メモリは既定では使われないことを意味します。さらに、次のような MVP 以降の提案もサポートします：

- multi-value
- JS string builtins

互換性を高めるため、`init` 関数は [`start` 関数](https://webassembly.github.io/spec/core/syntax/modules.html#start-function) としてコンパイルされ、`main` 関数は `_start` としてエクスポートされます。

##### NOTE
Wasm バックエンドでは、外部世界とやり取りする関数はすべてホストに依存します。例えば、Wasm と Wasm GC バックエンドの `println` は、呼び出しごとに UTF-16 コードユニットを 1 つ出力する `spectest.print_char` という関数のインポートに依存します。標準ライブラリの `env` パッケージや `moonbitlang/x` の一部のパッケージは、MoonBit ランタイム用に定義された特定のホスト関数に依存します。生成した Wasm の移植性を高めたいなら、これらは使わないでください。

#### JavaScript

JavaScript バックエンドは JavaScript ファイルを生成します。これは [configuration](../toolchain/moon/package.md#js-backend-link-options) に応じて CommonJS モジュール、ES モジュール、IIFE のいずれかになります。

#### C

C バックエンドは C ファイルを生成します。MoonBit ツールチェーンは、[configuration](../toolchain/moon/package.md#native-backend-link-options) に基づいてプロジェクトをコンパイルし、実行ファイルも生成します。

#### LLVM

LLVM バックエンドはオブジェクトファイルを生成します。このバックエンドは実験段階であり、FFI をサポートしません。

### 外部型の宣言

`#external` 属性を使うと、次のように外部型を宣言できます：

```moonbit
##external
type ExternalRef
```

#### Wasm と Wasm GC

これは [`externref`](https://webassembly.github.io/spec/core/syntax/types.html#reference-types) として解釈されます。

#### JavaScript

これは JavaScript の値として解釈されます。

#### C

これは `void*` として解釈されます。

### 外部関数の宣言

外部の世界とやり取りするには、外部関数を宣言できます。

##### NOTE
MoonBit は多相的な外部関数をサポートしていません。

##### IMPORTANT
関数を宣言するときは、シグネチャが実際の外部関数と対応していることを確認する必要があります。**外部関数が値を返さない場合は `-> Unit` を使ってください。これは C では `void` に、Wasm では結果を持たない関数に対応します。**

#### Wasm と Wasm GC

外部関数を宣言する方法は 2 つあります。関数をインポートするか、インライン関数を書くかです。

ランタイムホストから、モジュール名と関数名を指定して関数をインポートできます：

```moonbit
fn cos(d : Double) -> Double = "math" "cos"
```

あるいは、Wasm 構文を使ってインライン関数を書くこともできます：

```moonbit
extern "wasm" fn identity(d : Double) -> Double =
  #|(func (param f64) (result f64))
```

##### NOTE
インライン関数を書くときは、関数名を指定しないでください。

#### JavaScript

外部関数を宣言する方法は 2 つあります。関数をインポートするか、インライン関数を書くかです。

モジュール名と関数名を指定して関数をインポートできます。これは `module.function` として解釈されます。例えば：

```moonbit
fn cos(d : Double) -> Double = "Math" "cos"
```

これは `const cos = (d) => Math.cos(d)` という関数を指します。

あるいは、JavaScript のラムダを定義するインライン関数を書くこともできます：

```moonbit
extern "js" fn cos(d : Double) -> Double =
  #|(d) => Math.cos(d)
```

#### C

関数名を指定して関数をインポートすることで、外部関数を宣言できます：

```moonbit
extern "C" fn put_char(ch : UInt) -> Unit = "function_name"
```

パッケージが外部 C ライブラリと動的リンクする必要がある場合は、`moon.pkg` に `cc-link-flags` を追加してください。これは C コンパイラに直接渡されます。

```moonbit
options(
  "link": {
    "native": {
      "cc-link-flags": "-l<c library>"
    }
  },
)
```

ラッパー関数を定義するには、パッケージに C スタブファイルを追加し、そのパッケージの `moon.pkg` に次を追加します：

```moonbit
options(
  "native-stub": [ 
    // list of stub file names
  ],
)
```

おそらく `#include "moonbit.h"` を使いたくなるはずです。これには MoonBit の C インターフェース向けの型定義と便利なユーティリティが含まれています。ヘッダは `~/.moon/include` にあり、詳細はその中身を確認してください。

#### 型

下の表は、いくつかの MoonBit 型の内部表現を示しています：

#### 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
数値用の `FixedArray[T]` は、将来的に `TypedArray` に移行する可能性があります。

#### 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
`Unit` を返す外部関数は、`void` を返す C 関数に対応します。`FuncRef[T]` の `T` の戻り値型が `Unit` の場合、それは `void` を返す関数を指します。

上で触れていない型には安定した ABI がないため、その内部表現に依存したコードを書くべきではありません。

#### コールバック

ときには、MoonBit の関数をコールバックとして外部インターフェースに渡したくなります。MoonBit ではクロージャを扱えます。[MDN glossary](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Closures) によると：

> クロージャとは、関数と、その周囲の状態（レキシカル環境）への参照をひとまとめにしたものです。言い換えると、クロージャによって関数は外側のスコープにアクセスできます。JavaScript では、関数が作られるたびにクロージャが作成されます。

場合によっては、ローカルな自由変数を一切捕捉しないコールバック関数を渡したいことがあります。そのために MoonBit では、型 `T` の閉じた関数を表す特別な型 `FuncRef[T]` を用意しています。`FuncRef[T]` 型の値は、型 `T` の閉じた関数でなければならず、そうでない場合は [型エラー](error_codes/E4151.md) が発生します。

それ以外の場合、MoonBit の関数引数は、関数と周囲の状態を保持するオブジェクトとして表現されます。

#### Wasm と Wasm GC

Wasm バックエンドでは、コールバックはホストの関数を表す `externref` として渡されます。ただし、関数と捕捉したデータをまとめてホスト側の関数に変換することが重要です。

そのために、Wasm モジュールは `moonbit:ffi` モジュール、関数名 `make_closure` の関数をインポートします。この関数は関数とオブジェクトを受け取り、関数の最初の引数がそのオブジェクトであるものを、ホストの関数として返す必要があります。つまり、部分適用はホスト側の責任です。実装例は次のとおりです：

```javascript
{ 
  "moonbit:ffi": {
    "make_closure": (funcref, closure) => funcref.bind(null, closure)
  } 
}
```

#### JavaScript

JavaScript はクロージャをサポートしているので、ここで特別なことは必要ありません。

#### C

C ライブラリの関数の中には、コールバック関数に加えて追加データを渡せるものがあります。次の C ライブラリ関数があるとします：

```c
void register_callback(void (*callback)(void*), void *data);
```

この C 関数をバインドし、次の工夫でクロージャを渡すことができます：

```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
  )
}
```

`FuncRef[_]` 型の値は、MoonBit から直接呼び出すこともできます。これは、シンボル名で関数を動的に読み込む場合や、ネイティブバックエンドで JIT を実装する場合に便利です。

#### 定数 enum の整数値をカスタマイズする

MoonBit のすべてのバックエンドで、定数 enum（すべてのコンストラクタがペイロードを持たない `enum`）は整数に変換されます。コンストラクタ宣言の後に `= <integer literal>` を追加すると、各コンストラクタの実際の整数表現をカスタマイズできます：

```moonbit
enum SpecialNumbers {
  Zero = 0
  One
  Two
  Three
  Ten = 10
  FourtyTwo = 42
}
```

コンストラクタの整数値を指定しない場合は、直前のコンストラクタの値に 1 を加えた値が既定になります（最初のコンストラクタは 0 です）。この機能は、C ライブラリのフラグをバインドするときに特に便利です。

### 関数のエクスポート

メソッドでも多相関数でもない public 関数は、[link configuration](../toolchain/moon/package.md#link-options) の `exports` フィールドを設定することでエクスポートできます。

```moonbit
options(
  "link": {
    "<backend>": {
      "exports": [ "add", "fib:test" ]
    }
  }
)
```

前の例では `add` と `fib` をエクスポートしますが、`fib` は `test` としてエクスポートされます。

#### Wasm と Wasm GC

##### NOTE
これは設定したパッケージにのみ有効で、下流のパッケージには影響しません。

#### JavaScript

##### NOTE
これは設定したパッケージにのみ有効で、下流のパッケージには影響しません。

CommonJS モジュール（`cjs`）、ES Module（`esm`）、`iife` としてエクスポートするための別の `format` オプションもあります。

#### C

##### NOTE
これは設定したパッケージにのみ有効で、下流のパッケージには影響しません。

エクスポートした関数の名前変更は、現時点ではサポートしていません

### ライフタイム管理

MoonBit はガベージコレクションを持つプログラミング言語です。そのため、外部オブジェクトを扱うときや MoonBit オブジェクトをホストに渡すときは、ライフタイム管理を意識することが重要です。現在、MoonBit は Wasm バックエンドと C バックエンドでは参照カウントを使います。Wasm GC バックエンドと JavaScript バックエンドでは、ランタイムの GC を再利用します。

#### 外部オブジェクトのライフタイム管理

MoonBit で外部オブジェクトやリソースを扱うときは、メモリやリソースのリークを防ぐために、適切なタイミングでオブジェクトを破棄したりリソースを解放したりすることが重要です。

##### NOTE
C バックエンドのみ

`moonbit.h` には、MoonBit 独自の自動メモリ管理システムを使って外部オブジェクトやリソースのライフタイムを扱うための API `moonbit_make_external_object` があります：

```c
void *moonbit_make_external_object(
  void (*finalize)(void *self),
  uint32_t payload_size
);
```

`moonbit_make_external_object` は、サイズが `payload_size + sizeof(finalize)` の新しい MoonBit オブジェクトを作成します。オブジェクトのレイアウトは次のとおりです：

```default
| MoonBit object header | ... payload | finalize function |
                        ^
                        |
                        |_
                           pointer returned by `moonbit_make_external_object`
```

そのため、オブジェクトをそのペイロードへのポインタとして直接扱えます。MoonBit の自動メモリ管理システムが、`moonbit_make_external_object` で作成されたオブジェクトがもう生きていないと判断すると、オブジェクト自身を引数として `finalize` 関数を呼び出します。これにより `finalize` は、オブジェクトのペイロードが保持していた外部リソースやメモリを解放できます。

##### NOTE
`finalize` はオブジェクト自身を解放してはいけません。これは MoonBit ランタイムが処理します。

MoonBit 側では、`moonbit_make_external_object` が返すオブジェクトは、`type T` で宣言した *abstract* 型に束縛しておくべきです。そうすることで、MoonBit のメモリ管理システムがそのオブジェクトを無視しなくなります。

#### MoonBit オブジェクトのライフタイム管理

関数を通して MoonBit オブジェクトをホストに渡すときは、MoonBit 自体のライフタイム管理に注意することが重要です。前述のとおり、MoonBit の Wasm バックエンドと C バックエンドは、コンパイラ最適化された参照カウントでオブジェクトのライフタイムを管理します。メモリエラーやリークを避けるため、FFI 関数は MoonBit オブジェクトの参照カウントを適切に維持しなければなりません。

##### NOTE
C バックエンドと Wasm バックエンドのみ

##### 参照カウントの呼び出し規約

既定では、MoonBit は参照カウントに owned 呼び出し規約を使います。つまり、被呼び出し側（呼び出される関数）が、`moonbit_decref` / `$moonbit.decref` 関数を使って引数を解放する責任を持ちます。引数を複数回使う場合は、被呼び出し側が `moonbit_incref` / `$moonbit.incref` 関数を使って参照カウントを増やす必要があります。状況ごとに必要な操作は次のとおりです：

| イベント          | 操作       |
|---------------|----------|
| フィールド / 要素を読む | なし       |
| データ構造に格納する    | `incref` |
| MoonBit 関数に渡す | `incref` |
| 他の外部関数に渡す     | なし       |
| 返す            | なし       |
| スコープ末尾（返さない）  | `decref` |

例えば、ファイルを開く標準の `open` 関数に対する、ライフタイムが正しいバインディングは次のようになります：

```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;
}
```

##### 管理対象の型

次の型は常に unboxed であり、ライフタイムを管理する必要はありません：

- `Int` や `Double` などの組み込み数値型
- 定数 `enum`（すべてのコンストラクタがペイロードを持たない `enum`）

次の型は常に boxed で、参照カウントされます：

- `FixedArray[T]`、`Bytes`、`String`
- abstract 型（`type T`）

外部型（`#external type T`）も boxed ですが、これは外部ポインタを表すため、MoonBit はそれらに対して参照カウント操作を行いません。

ペイロード付きの `struct` / `enum` のレイアウトは、現時点では安定していません。

##### `borrow` と `owned` 属性

FFI を通して引数を渡すとき、その所有権が維持される場合とされない場合があります。`#borrow` と `#owned` 属性を使うと、この 2 つの条件を指定できます。

##### WARNING
既定の意味論は `#owned` から `#borrow` へ移行中です

`#borrow` と `#owned` の構文は次のとおりです：

```moonbit
##borrow(params..)
extern "C" fn c_ffi(..) -> .. = ..
```

ここで `params` は `c_ffi` の引数の部分集合です。

`#borrow` の引数は borrow ベースの呼び出し規約で渡されます。つまり、呼び出される関数はこれらの引数を `decref` する必要がありません。FFI 関数が引数をローカルに読むだけなら（つまり引数を返さず、データ構造にも保存しないなら）、`#borrow` 属性を直接使えます。例えば、前述の `open` 関数は `#borrow` を使うと次のように書き換えられます：

```moonbit
##borrow(filename)
extern "C" fn open(filename : Bytes, flags : Int) -> Int = "open"
```

もはやスタブ関数は不要です。ここでは `open` の元の版に直接バインドしています。`#borrow` 属性を使っても、この版はライフタイム的に正しいままです。

他の理由でスタブ関数が必要な場合でも、`#borrow` によってライフタイム管理を簡単にできることがよくあります。**borrow 引数** に対して必要な操作は、状況ごとに次のとおりです：

| イベント                                 | 操作       |
|--------------------------------------|----------|
| フィールド / 要素を読む                        | なし       |
| データ構造に格納する                           | `incref` |
| MoonBit 関数に渡す                        | `incref` |
| 他の C 関数 / `#borrow` 付き MoonBit 関数に渡す | なし       |
| 返す                                   | `incref` |
| スコープ末尾（返さない）                         | なし       |

反対に `#owned` は、引数が FFI 関数側で保持され、後で `decref` を手動で実行する必要がある意味論です。利用例の 1 つは、クロージャが **owned** になるコールバックの登録です。

<!-- path: language/async-experimental.md -->
## 非同期プログラミングのサポート

MoonBit は、[Kotlin](https://kotlinlang.org/docs/coroutines-overview.html) に似たコルーチンベースの非同期プログラミング方式を採用しています。MoonBit の非同期プログラミングは 2 つの要素から成ります。1 つは `async` 関数に対するコンパイラサポート、もう 1 つは公式の非同期ランタイム `moonbitlang/async` です。現在、`moonbitlang/async` は native バックエンドを最もよくサポートし、JavaScript バックエンドは限定的にサポートしていますが、WebAssembly バックエンドはまだサポートしていません。`moonbitlang/async` の API は安定版とは見なされておらず、将来変更される可能性があります。

<!-- We highly appreciate any feedback or experiment with current design. -->

### はじめに

`moonbitlang/async` を使って非同期プログラミングを行うには、まずプロジェクトで `moon add moonbitlang/async@0.19.2` を実行して、`moonbitlang/async` を依存関係に追加してください。`moon.mod.json` で `"preferred-target": "native"` を設定しておくのもよいでしょう。次に、`moon.pkg` で `moonbitlang/async` と `moonbitlang/async` ライブラリ内の他のパッケージを import すれば、非同期プログラミング API を使えるようになります。ワークフロー重視の例が見たい場合は、[Native CLI Quickstart](../tutorial/cli-quickstart.md) を参照してください。

`moonbitlang/async` に含まれるパッケージ一覧と詳細なドキュメントは [mooncakes.io](https://mooncakes.io/docs/moonbitlang/async) で確認でき、`moonbitlang/async` の GitHub リポジトリには便利な [examples](https://github.com/moonbitlang/async/tree/main/examples) もあります。この記事では、`moonbitlang/async` の基本的な概念と、特に重要な API をいくつか紹介します。

### Async 関数

Async 関数は `async` キーワードで宣言します。これらは暗黙に [`raise`](error-handling.md#throwing-errors) し、そうでない場合は `noraise` を明示的に宣言する必要があります。

```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()
}
```

MoonBit は静的型付け言語なので、コンパイラが async であることを追跡します。そのため、async 関数は通常の関数と同じように呼び出せます。MoonBit IDE では、async 関数の呼び出しが別のスタイルで強調表示されます。上のコードスニペットをMoonBit IDE で開くと、`@http.get` 関数が下線付きの斜体で表示されるはずです。

Async 関数は async 関数の内部からしか呼び出せません。`async` 関数を呼び出すと、呼び出し元はブロックされ、呼び出し先が返るまで待機します。これは多くの他の言語における `await` に似ています。

MoonBit は非同期プログラミングを第一級にサポートしています。`async fn main` で非同期のプログラムエントリを宣言でき、`async test` で非同期コードのテストを書けます。非同期テストは、デフォルトで自動的に並列実行されます。`async fn main` と `async test` を使うには、パッケージ内で `moonbitlang/async` を import する必要がある点に注意してください。

### 構造化並行性とタスクグループ

非同期プログラムが async 関数を直接呼び出すだけ（つまり `await` だけを使う）なら、その制御フローは線形で、通常の同期プログラミングと変わりません。非同期プログラムと同期プログラムの根本的な違いは、複数のタスクを生成して並列に実行できることです。この能力は、同時実行タスクによってプログラムの制御フローが大幅に複雑になるため、タスクを堅牢に管理するという新しい課題も生みます。

`moonbitlang/async` ライブラリは、タスク管理の問題を解決し、非同期プログラムの堅牢性を高めるために  *構造化並行性* のパラダイムを採用しています。`moonbitlang/async` では、新しいタスクを生成できるのは *task group* の内部のみであり、task group は `@async.with_task_group` 関数を通じてのみ作成できます：

```moonbit
async fn[Result] with_task_group(
  f : async (@async.TaskGroup[Result]) -> Result,
) -> Result
```

`with_task_group` 関数は新しい task group を作成し、その task group の中で新しいタスクを生成し、グループ自身を引数として `f` を新しいタスクの中で実行します。`f` はその後、`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
```

構造化並行性の肝は、`with_task_group` に対する次の規則にあります：

> `with_task_group` は、グループ内のすべてのタスクが終了した後でのみ戻ります

`with_task_group` は、どのような条件でも上記の性質を保証します。通常は、`with_task_group` はタスクが普通に完了するのを待つだけです。致命的なエラーなどの理由で `with_task_group` をすぐに終了する必要がある場合（デフォルトでは、子タスクのいずれかが失敗すると `with_task_group` 自体もすぐに失敗し、エラーが黙って無視されないようにします）、すべての子タスクを適切にキャンセルし、そのクリーンアップ処理が終わるまで待ちます。要するに、`with_task_group` の規則により、 *孤児タスク*（プログラムがキャンセルし忘れたせいで動き続ける不要なタスク）が `moonbitlang/async` で存在し得なくなります。

`with_task_group` を使って複数のタスクを作成し、並列に実行させる簡単な例は次のとおりです：

```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` は非常に強力な構文です。多くの非同期制御フローを模倣できます。例えば、非同期関数をタイムアウト付きで実行する関数は次のように書けます：

```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()
  })
}
```

コード自体はとても単純ですが、`with_task_group` の意味論により、この単純な関数があらゆる境界ケースで正しく動作することが保証されます：

- `f` がタイムアウト前に正常終了した場合、sleep タスクは `no_wait=true` で生成されているので、`with_task_group` は sleep タスクを待ちません。その規則を守るために、`with_task_group` は sleep タスクをただちにキャンセルします。したがって `with_timeout(.., f)` は、`f` が返った直後に不要な遅延なしで戻ります。
- `f` が失敗した場合、そのエラーは `with_task_group` 全体に伝播します。この場合も sleep タスクは自動的にキャンセルされます。
- タイムアウト時点で `f` がまだ実行中なら、sleep タスクが致命的なタイムアウトエラーを送出し、グループ全体が中断されます。この場合も `f` は自動的にキャンセルされます。

### キャンセルによって非同期プログラムはモジュール化される

前の節では「キャンセル」という言葉が何度も出てきました。実際、キャンセルは非同期プログラミングで非常に重要な要素です。`moonbitlang/async` では、`with_task_group` を含むすべての非同期操作がデフォルトでキャンセル可能です。そのため、これらの基本的な非同期操作を組み合わせてより大きなプログラムを作っても、どれほど複雑であっても自動的にキャンセル可能になります。

非同期コードの一部がキャンセルされると、そのキャンセル信号は、以前ブロックしていた地点で送出されるエラーとして表現されます。そのため、キャンセルを特別に処理する必要はありません。キャンセル信号は自動的にプログラム全体に伝播し、`defer` やエラーハンドラ内のクリーンアップ処理を発火させます。

任意の async コードをキャンセルできることにより、MoonBit の async プログラムは非常にモジュール化しやすくなります。`moonbitlang/async` パッケージには、タイムアウト制限や自動リトライなどを行う便利な combinator が多数あり、それらはすべてキャンセル機構に依存して正しく動作します。例えば、次のプログラムは HTTP リクエストをタイムアウト付きで試み、リトライ回数は最大 3 回に制限します：

```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()
    })
  })
}
```

### 外部世界とのやり取り

`moonbitlang/async` は、非同期プログラミングのプリミティブに加えて、非同期 IO 操作用のイベントループも提供します。さらに、`http`/`https`、ファイル IO、ソケット IO、プロセス生成など、豊富な IO 操作を [十分な性能](https://www.moonbitlang.com/blog/moonbit-async#performance-comparison) 付きで備えています。サポートされる操作の完全な一覧とそのドキュメントは [mooncakes.io](https://mooncakes.io/docs/moonbitlang/async) に、簡単な例は [GitHub リポジトリ](https://github.com/moonbitlang/async/tree/main/examples) にあります。以下では、よく使う機能をいくつか手早く見てみましょう：

```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 サポート

`moonbitlang/async` は native バックエンドを最もよくサポートしますが、JavaScript バックエンドも基本的にサポートしています：

- task group や timeout など、IO に依存しない API はすべて利用できます
- IO 関連 API は利用できません。なぜなら、すべての JavaScript 実行環境（たとえばブラウザ）がそれらをサポートしているわけではないからです
- `moonbitlang/async/js_async` は、外部の JavaScript Promise を待機したり、MoonBit の `async` 関数を JavaScript Promise として公開したりするなど、JavaScript Promise との統合をサポートします。これにより、JavaScript ホストのネイティブな非同期操作とやり取りできます。

詳細は [moonbitlang/async/js_async の mooncakes.io ページ](https://mooncakes.io/docs/moonbitlang/async/js_async) を参照してください。

<!-- 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)
* [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)
* [E0076](E0076.md)
* [E0077](E0077.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)
* [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)
* [E4199](E4199.md)
* [E4200](E4200.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)
