# Hack Standard Library (HSL) コードリーディングガイドライン

## はじめに

このガイドラインは、Hack Standard Library (HSL)のコードベースを効率的に理解するための手引きです。
Hack言語に精通していないエンジニアでも、段階的に学習できるよう構成されています。

**対象読者:**
- プロジェクトに新規参画するエンジニア
- PHP/他言語からの経験者
- コードレビューを行う担当者

---

## 1. 言語基礎

> このセクションでは、Hack言語の基本構文と概念を解説します。

### 1.1 プログラム構造

Hackファイルは `<?hh` タグで始まります。PHPと異なり、Hackは完全に型付けされた言語です。

```hack
// ファイル: src/Ref.php:1-11
<?hh
/*
 *  Copyright (c) 2004-present, Facebook, Inc.
 *  All rights reserved.
 *
 *  This source code is licensed under the MIT license found in the
 *  LICENSE file in the hphp/hsl/ subdirectory of this source tree.
 *
 */

namespace HH\Lib;
```

すべてのソースファイルは名前空間内で定義されます。HSLでは主に `HH\Lib` 配下の名前空間を使用します。

### 1.2 データ型と変数

Hackは静的型付け言語で、ジェネリクスをサポートします。HSLで頻繁に使用される型：

| 型 | 説明 | 例 |
|---|---|---|
| `vec<T>` | 順序付きの値の配列 | `vec[1, 2, 3]` |
| `dict<Tk, Tv>` | キー・値のマップ | `dict['a' => 1]` |
| `keyset<T>` | ユニークな値の集合 | `keyset['a', 'b']` |
| `Traversable<T>` | 反復可能なコレクション | - |
| `Container<T>` | コンテナ型 | - |

```hack
// ファイル: src/dict/select.php:56-66
function drop<Tk as arraykey, Tv>(
  KeyedTraversable<Tk, Tv> $traversable,
  int $n,
)[]: dict<Tk, Tv> {
  invariant($n >= 0, 'Expected non-negative N, got %d.', $n);
  $result = dict[];
  $ii = -1;
  foreach ($traversable as $key => $value) {
    $ii++;
    if ($ii < $n) {
      continue;
    }
    $result[$key] = $value;
  }
  return $result;
}
```

### 1.3 制御構造

Hackの制御構造はPHPと類似していますが、型安全性が強化されています。

```hack
// ファイル: src/c/select.php:88-98
function first<T>(
  Traversable<T> $traversable,
)[]: ?T {
  if ($traversable is Container<_>) {
    return _Private\Native\first($traversable);
  }
  foreach ($traversable as $value) {
    return $value;
  }
  return null;
}
```

**`is` 演算子**: 型チェックに使用（上記例の `$traversable is Container<_>`）

**`invariant()`**: 条件が満たされない場合に例外をスロー

```hack
// ファイル: src/dict/select.php:55
invariant($n >= 0, 'Expected non-negative N, got %d.', $n);
```

### 1.4 関数/メソッド定義

Hackの関数定義は戻り値の型注釈と係数（capabilities）を含みます。

```hack
// ファイル: src/str/transform.php:26-31
function capitalize(string $string)[]: string {
  if ($string === '') {
    return '';
  }
  return _Str\uppercase_l(slice($string, 0, 1)).slice($string, 1);
}
```

**係数（Capabilities）**:
- `[]`: 純粋関数（副作用なし）
- `[ctx $value_predicate]`: コールバックのコンテキストを継承
- `[write_props]`: プロパティへの書き込みを許可

```hack
// ファイル: src/dict/select.php:79-91
function filter<Tk as arraykey, Tv>(
  KeyedTraversable<Tk, Tv> $traversable,
  ?(function(Tv)[_]: bool) $value_predicate = null,
)[ctx $value_predicate]: dict<Tk, Tv> {
  $value_predicate ??= \HH\Lib\_Private\boolval<>;
  $dict = dict[];
  foreach ($traversable as $key => $value) {
    if ($value_predicate($value)) {
      $dict[$key] = $value;
    }
  }
  return $dict;
}
```

### 1.5 モジュール/インポート

名前空間とuseステートメントでモジュールをインポートします。

```hack
// ファイル: src/vec/combine.php:11-13
namespace HH\Lib\Vec;

use namespace HH\Lib\{C, Math};
```

**インポートパターン**:
- `use namespace HH\Lib\C;` - 名前空間をインポート（`C\first()`として使用）
- `use type SomeClass;` - 型/クラスをインポート
- `use function some_func;` - 関数をインポート

---

## 2. プロジェクト固有の概念

> このセクションでは、HSL特有の概念を解説します。

### 2.1 フレームワーク固有の概念

HSLは標準ライブラリであり、以下の主要カテゴリの関数を提供します：

| 名前空間 | 役割 | 主な操作 |
|---------|------|---------|
| `HH\Lib\Vec` | vec配列操作 | map, filter, sort |
| `HH\Lib\Dict` | dict連想配列操作 | filter, merge, map |
| `HH\Lib\Keyset` | keyset集合操作 | diff, intersect, filter |
| `HH\Lib\C` | コンテナ汎用操作 | first, last, count |
| `HH\Lib\Str` | 文字列操作 | replace, split, join |
| `HH\Lib\Math` | 数学演算 | min, max, abs |
| `HH\Lib\Async` | 非同期処理 | Semaphore, Condition |
| `HH\Lib\IO` | 入出力操作 | Handle, BufferedReader |
| `HH\Lib\File` | ファイル操作 | open, temporary_file |
| `HH\Lib\OS` | OS低レベル操作 | pipe, socket |

### 2.2 プロジェクト独自のパターン

**1. イミュータブルな操作**

すべての関数は新しい値を返し、入力を変更しません。

```hack
// ファイル: src/vec/combine.php:25-36
function concat<Tv>(
  Traversable<Tv> $first,
  Container<Tv> ...$rest
)[]: vec<Tv> {
  $result = cast_clear_legacy_array_mark($first);
  foreach ($rest as $traversable) {
    foreach ($traversable as $value) {
      $result[] = $value;
    }
  }
  return $result;
}
```

**2. Nullable安全なバリアント**

多くの関数に `x` サフィックス（例外をスロー）と通常版（nullを返す）があります。

```hack
// ファイル: src/c/select.php:24-34 (nullを返す版)
function find<T>(
  Traversable<T> $traversable,
  (function(T)[_]: bool) $value_predicate,
)[ctx $value_predicate]: ?T {
  foreach ($traversable as $value) {
    if ($value_predicate($value)) {
      return $value;
    }
  }
  return null;
}

// ファイル: src/c/select.php:45-55 (例外をスローする版)
function findx<T>(
  Traversable<T> $traversable,
  (function(T)[_]: bool) $value_predicate,
)[ctx $value_predicate]: T {
  foreach ($traversable as $value) {
    if ($value_predicate($value)) {
      return $value;
    }
  }
  invariant_violation('%s: Couldn\'t find target value.', __FUNCTION__);
}
```

**3. 非同期処理パターン**

HSLは `async`/`await` を使用した非同期処理をサポートします。

```hack
// ファイル: src/async/Semaphore.php:47-86
public async function waitForAsync(Tin $value): Awaitable<Tout> {
  $gen = async {
    if (
      $this->runningCount + $this->recentOpenCount >= $this->concurrentLimit
    ) {
      // 同時実行数制限のため待機
      $condition = new Condition();
      $this->blocking[$unique_id] = $condition;
      await $condition->waitForNotificationAsync($this->activeGen);
    }
    // 処理を実行
    $f = $this->f;
    $this->runningCount++;
    try {
      return await $f($value);
    } finally {
      $this->runningCount--;
      // 次の待機中タスクを起動
    }
  };
  // ...
}
```

---

## 3. 命名規則

> このセクションでは、プロジェクト全体で使用される命名規則を解説します。

### 3.1 ファイル・ディレクトリ命名

| パターン | 意味 | 例 |
|---------|------|-----|
| `lowercase.php` | 関数定義ファイル | `combine.php`, `select.php` |
| `PascalCase.php` | クラス/インターフェース定義 | `Semaphore.php`, `Handle.php` |
| `_Private/` | 内部実装用ディレクトリ | `src/io/_Private/` |
| 機能カテゴリ名 | モジュールディレクトリ | `vec/`, `dict/`, `str/` |

### 3.2 クラス・関数・変数命名

| プレフィックス/サフィックス | 意味 | 例 |
|---------------------------|------|-----|
| `x` サフィックス | 失敗時に例外をスロー | `firstx()`, `findx()` |
| `_async` サフィックス | 非同期バージョン | `filter_async()` |
| `_ci` サフィックス | 大文字小文字を区別しない | `replace_ci()` |
| `_with_key` サフィックス | キーも引数に取る | `filter_with_key()` |
| `_l` サフィックス | ロケール対応版 | `uppercase_l()` |
| `n` プレフィックス | nullable入力を受け付ける | `nfirst()` |
| `_Private` | 内部実装用 | `_Private\boolval()` |
| `Closeable` プレフィックス | close可能なリソース | `CloseableHandle` |

### 3.3 プログラム分類一覧

| 分類 | ファイルパターン | 役割 |
|------|-----------------|------|
| Transform | `transform.php` | 値の変換操作 |
| Select | `select.php` | 要素の選択・抽出 |
| Combine | `combine.php` | 結合・連結操作 |
| Divide | `divide.php` | 分割操作 |
| Order | `order.php` | ソート・順序操作 |
| Introspect | `introspect.php` | 検査・判定操作 |
| Async | `async.php` | 非同期操作 |

---

## 4. ディレクトリ構造

> このセクションでは、プロジェクトのディレクトリ構造を解説します。

```
hsl-main/
├── src/                    # ソースコード
│   ├── Ref.php            # 参照ラッパークラス
│   ├── private.php        # 内部ユーティリティ
│   ├── _Private/          # プロジェクト全体の内部実装
│   ├── vec/               # vec配列操作
│   ├── dict/              # dict連想配列操作
│   ├── keyset/            # keyset集合操作
│   ├── c/                 # コンテナ汎用操作
│   ├── str/               # 文字列操作
│   ├── math/              # 数学演算
│   ├── regex/             # 正規表現
│   ├── random/            # 乱数生成
│   ├── async/             # 非同期処理
│   ├── io/                # 入出力
│   ├── file/              # ファイル操作
│   ├── os/                # OS低レベル操作
│   ├── network/           # ネットワーク共通
│   ├── tcp/               # TCP通信
│   ├── unix/              # Unixソケット
│   ├── locale/            # ロケール処理
│   └── legacy_fixme/      # レガシー互換性
├── tests/                  # テストコード
│   ├── vec/               # vecテスト
│   ├── dict/              # dictテスト
│   └── ...                # 各モジュールのテスト
├── minitest/              # テストフレームワーク
│   ├── main.hack          # テストランナー
│   ├── HackTest.hack      # テスト基底クラス
│   ├── ExpectObj.hack     # アサーション
│   └── DataProvider.hack  # データプロバイダー
├── .hhconfig              # Hackタイプチェッカー設定
├── dune                   # ビルド設定（OCaml/Dune）
└── README.md              # プロジェクト説明
```

### 各ディレクトリの役割

| ディレクトリ | 役割 | 主要ファイル |
|-------------|------|-------------|
| `src/vec/` | vec配列の操作関数 | `combine.php`, `transform.php`, `select.php` |
| `src/dict/` | dict連想配列の操作関数 | `select.php`, `combine.php`, `transform.php` |
| `src/c/` | 汎用コンテナ操作 | `select.php`, `introspect.php`, `reduce.php` |
| `src/str/` | 文字列操作関数 | `transform.php`, `select.php`, `introspect.php` |
| `src/async/` | 非同期処理クラス | `Semaphore.php`, `Condition.php`, `Poll.php` |
| `src/io/` | 入出力抽象化 | `Handle.php`, `BufferedReader.php` |
| `src/file/` | ファイル操作 | `Handle.php`, `open.php`, `TemporaryFile.php` |
| `src/os/` | OS低レベルAPI | `pipe.php`, `spawn.php`, `socket.php` |
| `tests/` | テストコード | `*Test.php` |
| `minitest/` | テストフレームワーク | `HackTest.hack`, `ExpectObj.hack` |

---

## 5. アーキテクチャ

> このセクションでは、プロジェクトのアーキテクチャパターンを解説します。

### 5.1 全体アーキテクチャ

HSLは**関数型ライブラリアーキテクチャ**を採用しています。

```
+--------------------------------------------------+
|                   利用者コード                     |
+--------------------------------------------------+
         |              |              |
         v              v              v
+----------------+ +----------------+ +----------------+
|   Vec\*        | |   Dict\*       | |   Str\*        |
| (配列操作)     | | (連想配列操作) | | (文字列操作)   |
+----------------+ +----------------+ +----------------+
         |              |              |
         v              v              v
+--------------------------------------------------+
|              HH\Lib\_Private                      |
|           (内部ヘルパー関数)                       |
+--------------------------------------------------+
         |
         v
+--------------------------------------------------+
|              HH\Lib\OS / Native                   |
|           (低レベルOS操作)                         |
+--------------------------------------------------+
```

### 5.2 レイヤー構成

| レイヤー | 責務 | 代表的なファイル |
|---------|------|-----------------|
| 公開API | ユーザー向け関数 | `src/vec/*.php`, `src/dict/*.php` |
| 内部実装 | 共通ヘルパー | `src/private.php`, `src/*/_Private/` |
| 低レベルAPI | OS/ネイティブ呼び出し | `src/os/*.php` |

### 5.3 データフロー

HSLの関数は一般的に以下のフローに従います：

1. **入力**: `Traversable<T>` / `Container<T>` / `KeyedTraversable<Tk, Tv>`
2. **処理**: イミュータブルな変換
3. **出力**: `vec<T>` / `dict<Tk, Tv>` / `keyset<T>`

```hack
// 典型的なデータフロー例
// src/vec/transform.php
$input = vec[1, 2, 3];
$result = Vec\map($input, $x ==> $x * 2);
// $result: vec[2, 4, 6]
```

---

## 6. 主要コンポーネント

> このセクションでは、主要なコンポーネントとその連携を解説します。

### 6.1 エントリーポイント

HSLはライブラリのため、明確なエントリーポイントはありません。各名前空間の関数を直接呼び出します。

テスト実行のエントリーポイント:

```hack
// ファイル: minitest/main.hack:8-9
<<__EntryPoint>>
async function main(): Awaitable<void> {
```

### 6.2 ビジネスロジック

各モジュールは特定のデータ型に対する操作を提供します。

**Vec操作の例:**

```hack
// ファイル: src/vec/combine.php:52-64
function zip<Tv, Tu>(
  Traversable<Tv> $first,
  Traversable<Tu> $second,
)[]: vec<(Tv, Tu)> {
  $one = cast_clear_legacy_array_mark($first);
  $two = cast_clear_legacy_array_mark($second);
  $result = vec[];
  $lesser_count = Math\minva(C\count($one), C\count($two));
  for ($i = 0; $i < $lesser_count; ++$i) {
    $result[] = tuple($one[$i], $two[$i]);
  }
  return $result;
}
```

### 6.3 データアクセス

HSLのIO/File名前空間がデータアクセス層を提供します。

```hack
// ファイル: src/io/Handle.php:47-48
interface Handle {
}
```

ファイル操作:

```hack
// src/file/open.php でファイルを開く
// src/io/BufferedReader.php で効率的に読み取り
```

### 6.4 ユーティリティ/共通機能

```hack
// ファイル: src/private.php:17-29
function validate_offset(int $offset, int $length)[]: int {
  $original_offset = $offset;
  if ($offset < 0) {
    $offset += $length;
  }
  invariant(
    $offset >= 0 && $offset <= $length,
    'Offset %d was out-of-bounds for length %d',
    $original_offset,
    $length,
  );
  return $offset;
}
```

---

## 7. よく使われるパターン

> このセクションでは、コード内で頻出するパターンを解説します。

### パターン一覧

| パターン | 説明 | 出現頻度 | 代表的なファイル |
|---------|------|---------|-----------------|
| イミュータブル変換 | 新しいコレクションを返す | 高 | すべての関数 |
| ジェネリクス | 型パラメータ化 | 高 | すべての関数 |
| Nullable/Xバリアント | null返却 vs 例外 | 高 | `c/select.php` |
| 係数（Capabilities） | 副作用の制御 | 高 | すべての関数 |
| DataProvider | テストデータ提供 | 中 | `tests/*.php` |

### 各パターンの詳細

#### パターン1: イミュータブル変換

**目的:** 入力を変更せず、新しい値を返す

**実装例:**
```hack
// ファイル: src/dict/select.php:145-155
function filter_nulls<Tk as arraykey, Tv>(
  KeyedTraversable<Tk, ?Tv> $traversable,
)[]: dict<Tk, Tv> {
  $result = dict[];
  foreach ($traversable as $key => $value) {
    if ($value !== null) {
      $result[$key] = $value;
    }
  }
  return $result;
}
```

**解説:** 元の `$traversable` は変更されず、null以外の値だけを含む新しいdictが返されます。

#### パターン2: Nullable/Xバリアント

**目的:** エラー処理の選択肢を提供

**実装例:**
```hack
// ファイル: src/c/select.php:329-361
function onlyx<T>(
  Traversable<T> $traversable,
  ?Str\SprintfFormatString $format_string = null,
  mixed ...$format_args
)[]: T {
  $first = true;
  $result = null;
  foreach ($traversable as $value) {
    invariant(
      $first,
      '%s',
      $format_string === null
        ? Str\format(
          'Expected exactly one element%s.',
          $traversable is Container<_>
            ? ' but got '.count($traversable)
            : '',
        )
        : \vsprintf($format_string, $format_args),
    );
    $result = $value;
    $first = false;
  }
  invariant(
    $first === false,
    '%s',
    $format_string === null
      ? 'Expected non-empty Traversable.'
      : \vsprintf($format_string, $format_args),
  );
  return $result;
}
```

#### パターン3: DataProviderパターン（テスト）

**目的:** テストデータを構造化して提供

**実装例:**
```hack
// ファイル: tests/vec/VecCombineTest.php:17-40
public static function provideTestConcat(): varray<mixed> {
  return vec[
    tuple(vec[], vec[], vec[]),
    tuple(
      vec['the', 'quick'],
      vec[
        Vector {'brown', 'fox'},
        Map {'jumped' => 'over'},
        HackLibTestTraversables::getIterator(vec['the', 'lazy', 'dog']),
      ],
      vec['the', 'quick', 'brown', 'fox', 'over', 'the', 'lazy', 'dog'],
    ),
  ];
}

<<DataProvider('provideTestConcat')>>
public function testConcat<Tv>(
  Traversable<Tv> $first,
  Container<Container<Tv>> $rest,
  vec<Tv> $expected,
): void {
  expect(Vec\concat($first, ...$rest))->toEqual($expected);
}
```

---

## 8. 業務フロー追跡の実践例

> このセクションでは、実際の業務フローをコードで追跡する方法を解説します。

### 8.1 フロー追跡の基本手順

1. エントリーポイントを特定
2. 処理の流れを追跡（呼び出し関係を追う）
3. データの変換を確認
4. 最終的な出力を確認

### 8.2 フロー追跡の実例

#### 例1: Dict\filterの動作フロー

**概要:** dict配列から条件に合う要素を抽出する

**処理フロー:**
```
Dict\filter() → 述語関数評価 → 新しいdictを構築 → 結果を返す
```

**詳細な追跡:**

1. **API呼び出し** (`src/dict/select.php:79-91`)
   ```hack
   function filter<Tk as arraykey, Tv>(
     KeyedTraversable<Tk, Tv> $traversable,
     ?(function(Tv)[_]: bool) $value_predicate = null,
   )[ctx $value_predicate]: dict<Tk, Tv> {
   ```

2. **デフォルト述語の設定** (`src/dict/select.php:83`)
   ```hack
   $value_predicate ??= \HH\Lib\_Private\boolval<>;
   ```
   - 述語が指定されない場合、`boolval`（真偽値変換）を使用

3. **フィルタリング処理** (`src/dict/select.php:84-90`)
   ```hack
   $dict = dict[];
   foreach ($traversable as $key => $value) {
     if ($value_predicate($value)) {
       $dict[$key] = $value;
     }
   }
   return $dict;
   ```

#### 例2: Semaphoreによる同時実行数制御

**概要:** 非同期処理の同時実行数を制限する

**処理フロー:**
```
Semaphore生成 → waitForAsync() → 制限チェック → 処理実行 → スロット解放
```

**詳細な追跡:**

1. **Semaphore生成** (`src/async/Semaphore.php:38-44`)
   ```hack
   public function __construct(
     private int $concurrentLimit,
     private (function(Tin): Awaitable<Tout>) $f,
   ) {
     invariant($concurrentLimit > 0, "Concurrent limit must be greater than 0.");
     $this->activeGen = async {};
   }
   ```

2. **実行待ち** (`src/async/Semaphore.php:47-61`)
   ```hack
   if ($this->runningCount + $this->recentOpenCount >= $this->concurrentLimit) {
     // 制限に達している場合、Conditionで待機
     $condition = new Condition();
     $this->blocking[$unique_id] = $condition;
     await $condition->waitForNotificationAsync($this->activeGen);
   }
   ```

3. **処理実行とスロット管理** (`src/async/Semaphore.php:67-80`)
   ```hack
   $this->runningCount++;
   try {
     return await $f($value);
   } finally {
     $this->runningCount--;
     // 次の待機中タスクを起動
     $next_blocked_id = C\first_key($this->blocking);
     if ($next_blocked_id !== null) {
       $this->recentOpenCount++;
       $next_blocked->succeed(null);
     }
   }
   ```

### 8.3 フロー追跡チェックリスト

- [ ] エントリーポイントを特定したか
- [ ] 呼び出し関係を把握したか
- [ ] データの変換ポイントを確認したか
- [ ] エラーハンドリング（invariant）を確認したか
- [ ] 最終的な出力を確認したか

---

## 9. 設計書の参照順序

> このセクションでは、プロジェクト理解のための設計書参照順序を案内します。

### 9.1 目的別ロードマップ

#### 全体像を把握したい場合
1. `README.md` - プロジェクト概要
2. `src/` ディレクトリ構造を確認
3. 各名前空間（vec, dict, str等）の関数一覧を確認

#### 特定機能を理解したい場合
1. 該当する名前空間のディレクトリを特定（例: `src/vec/`）
2. 機能分類ファイルを確認（transform.php, select.php等）
3. 対応するテストファイルで使用例を確認

#### 改修作業を行う場合
1. 対象関数のソースコードを確認
2. `_Private/` 内の内部実装を確認
3. `tests/` 内の対応するテストを確認
4. `.hhconfig` で型チェッカー設定を確認

### 9.2 ドキュメント一覧

| ドキュメント | 概要 | 参照タイミング |
|-------------|------|---------------|
| `README.md` | プロジェクト概要 | 最初に読む |
| `src/os/README.md` | OS操作の詳細説明 | OS操作を理解する際 |
| `.hhconfig` | 型チェッカー設定 | ビルド・型エラー時 |
| `dune` | ビルド設定 | ビルド問題時 |
| `minitest/README.md` | テストフレームワーク | テスト作成時 |

---

## 10. トラブルシューティング

> このセクションでは、コードリーディング時によくある問題と解決法を解説します。

### よくある疑問と回答

#### Q: `[]: T` の `[]` は何を意味しますか?
A: **係数（Capabilities）** を表します。`[]` は純粋関数（副作用なし）を意味します。`[ctx $f]` はコールバック `$f` のコンテキストを継承することを示します。

#### Q: `<Tk as arraykey>` の `as arraykey` は何ですか?
A: **型制約**です。`Tk` が `int` または `string`（arraykeyとして使える型）であることを要求します。

#### Q: `invariant()` と `invariant_violation()` の違いは?
A: `invariant($cond, $msg)` は条件が偽の場合に例外をスロー。`invariant_violation($msg)` は無条件に例外をスローします。

#### Q: `?T` と `T` の違いは?
A: `?T` は `T` または `null` を許容する nullable型です。`T` は null を許容しません。

#### Q: `_Private` ディレクトリの関数を使用してもいいですか?
A: いいえ。`_Private` は内部実装用であり、APIの安定性は保証されません。公開APIのみを使用してください。

### デバッグのヒント

1. **型エラー時**: `.hhconfig` の `allowed_fixme_codes_strict` を確認
2. **関数が見つからない時**: 名前空間のインポートを確認（`use namespace`）
3. **テスト失敗時**: `minitest/ExpectObj.hack` のアサーションメソッドを確認
4. **非同期処理のデバッグ**: `await` の位置と `Awaitable<T>` の型を確認

---

## 付録

### A. 用語集

| 用語 | 説明 |
|-----|------|
| HSL | Hack Standard Library |
| HHVM | HipHop Virtual Machine（Hackの実行環境） |
| Traversable | 反復可能なコレクションのインターフェース |
| Container | 要素を含むコンテナのインターフェース |
| KeyedContainer | キー付きコンテナのインターフェース |
| Awaitable | 非同期処理の結果を表す型 |
| Capabilities | 関数の副作用を制御する機能 |
| invariant | 条件を検証し、失敗時に例外をスロー |

### B. ファイル一覧

| ファイル/ディレクトリ | 説明 | 主な内容 |
|---------------------|------|---------|
| `src/vec/` | vec配列操作 | map, filter, sort等 |
| `src/dict/` | dict連想配列操作 | filter, merge等 |
| `src/keyset/` | keyset集合操作 | diff, intersect等 |
| `src/c/` | 汎用コンテナ操作 | first, last, count等 |
| `src/str/` | 文字列操作 | replace, join等 |
| `src/async/` | 非同期処理 | Semaphore, Condition等 |
| `src/io/` | 入出力 | Handle, BufferedReader |
| `src/file/` | ファイル操作 | open, TemporaryFile |
| `src/os/` | OS操作 | pipe, socket |
| `tests/` | テストコード | 全機能のテスト |
| `minitest/` | テストフレームワーク | HackTest, ExpectObj |

### C. 参考資料

- [Hack言語公式ドキュメント](https://docs.hhvm.com/hack/)
- [HHVM公式サイト](https://hhvm.com/)
- [HSL GitHubリポジトリ](https://github.com/hhvm/hsl)
- [HHVM本体リポジトリ（HSL移行先）](https://github.com/facebook/hhvm/tree/master/hphp/hsl)
