PHPの「配列」という呪縛を解け:HSLによる型安全なデータ構造への昇華
PHPの `array` を使い続けている限り、君のコードには常に「ランタイムエラー」という爆弾が埋め込まれている。
いいか、PHPの `array` は悪魔の産物だ。連想配列として振る舞うかと思えば、順序付きリストにもなり、時には `in_array` で $O(N)$ の探索を強いる集合にもなる。この「二重・三重の責務」が、堅牢なシステム構築の最大の足枷だ。
HHVMの深淵を知る者として断言する。Hackでの開発は、データを「型」の定義に従って `dict` と `keyset` に分離することから始まる。 これを怠る者は、将来のデバッグ地獄を約束されたようなものだ。
—
1. なぜ PHP の `array` は「罪」なのか
PHPの配列は、ハッシュテーブルと連結リストのハイブリッドだ。この柔軟性が「何でも入るゴミ箱」を生み出す。
- 型安全性の欠如: `array
` という暗闇。値の取り出し時にキャストが必要になる瞬間、君のロジックは崩壊している。 - 計算量の不透明さ: 集合(Set)として使っているつもりでも、内部はハッシュテーブル。`in_array` を呼ぶたびにHHVMは冷ややかな目で $O(N)$ の走査を行う。
これに対し、HSLの `dict` と `keyset` は、メモリレイアウトと計算量を最初から規定する。
2. 責務の分離:dict と keyset
`dict`:キーと値のマッピング(Map)
`dict` は、特定のキーに対して値を引き当てるための専用構造だ。順序は保証されるが、あくまで「キーと値のペア」の保持に特化する。
`keyset`:一意な要素の集合(Set)
`keyset` は、値そのものをキーとして扱う特殊なデータ構造だ。重複は許容されず、値の探索は最適化されたハッシュアルゴリズムにより $O(1)$ で完了する。
—
3. 実践:PHPの悪習をHSLでリファクタリングする
以下は、ユーザー権限を管理するよくあるPHPコードの、Hackによる「あるべき姿」だ。
非推奨:PHP的な `array` 依存コード
// 悪い例:arrayは中身が不明瞭で、探索も遅い
function has_permission(array $permissions, string $perm): bool {
// 集合として扱っているのに配列の全走査が発生する可能性がある
return in_array($perm, $permissions, true);
}
推奨:HSL を駆使した堅牢な設計
use namespace HH\Lib\{C, Keyset};
// dict: ユーザーIDと権限セットのマップ
type UserPermissions = dict
class PermissionManager {
private UserPermissions $data = dict[];
public function addPermission(int $userId, string $perm): void {
// dictの初期化を怠らない(疎なデータ構造の回避)
$userPerms = $this->data->get($userId) ?? keyset[];
// keysetへの追加は一意性が保証される
$this->data[$userId] = Keyset\append($userPerms, $perm);
}
public function hasPermission(int $userId, string $perm): bool {
// $this->data[$userId] が存在しなければ空のkeysetを返す
// contains は keyset に対して O(1) で動作する
return $this->data->get($userId)?->contains($perm) ?? false;
}
}
—
4. パフォーマンスを極限まで引き出すための「掟」
1. `C\contains` ではなく `keyset` のメソッドを使え
`keyset` を使用していれば、`$set->contains($item)` を呼ぶだけでいい。`C\contains` は引数として渡されたコレクションの型をチェックするオーバーヘッドがある。直接的なメソッド呼び出しは、HHVMのJIT最適化が最も効く経路だ。
2. 不要な `vec` への変換を避ける
`dict` や `keyset` をループして `vec` に変換する処理は、メモリの再確保を伴う。可能な限りストリーム的な処理(`Iter\map`, `Iter\filter`)を使い、メモリ消費を抑えろ。
3. 型定義をサボるな
`dict
—
結論:コードは「状態」ではなく「型」で語れ
君たちが書くコードは、単なるテキストではない。HHVMの仮想マシン上で実行される、精密な機械の設計図だ。
`array` という曖昧な箱を使うのは、ネジ穴のサイズを測らずに電動ドリルを回すようなものだ。今すぐ `dict` と `keyset` を使いこなし、データの構造を明確に定義せよ。
型システムを厳格にすればするほど、君たちのコードは自由になる。なぜなら、「何が起こりうるか」が保証されたコードには、無駄なチェックも、予期せぬクラッシュも存在しないからだ。
さあ、エディタを開いて、その汚れた `array` をすべて書き換える準備はできたか?