HackのGenericsは「ただの型補完」ではない。堅牢なシステムを構築するための「抽象化の武器」だ。
PHPの動的型付けに疲弊し、`mixed` の海で溺れている諸君へ。
Hackへの移行は、単なるシンタックスの変更ではない。HHVMのJITコンパイラが真価を発揮するための「契約」の締結だ。
今日は、PHPコードをHackのGenericsで再設計し、実行時エラーを排除しつつ、圧倒的な再利用性を手に入れるための「核心」を授ける。
—
1. なぜPHPの「型指定」は脆いのか
PHPでよく見るこのパターンを考えてみよう。
// 悪い例:PHPの動的設計
function getFirst(array $items) {
return $items[0] ?? null;
}
この関数は危険だ。`$items` が何を含んでいるか、戻り値が `null` なのか値なのか、呼び出し元は推測するしかない。結果、至る所で `is_array()` や `instanceof` のチェックが散らばり、コードベースは「防御的プログラミング」という名のゴミで埋め尽くされる。
HackのGenericsは、この「不確実性」をコンパイルタイムで完全に消し去る。
—
2. Genericsによる抽象化:堅牢なコンポーネント設計
HackのGenericsは、HHVMの型チェッカー `hh_client` が推論を完遂するための道標だ。`T` という型パラメータを導入することで、コードの「意図」をコンパイラに刻み込む。
実践:型安全なリポジトリパターン
外部APIのレスポンスやデータベースのエンティティを扱う際、Genericsを使って「型を注入」する設計がこれだ。
namespace App\Infrastructure;
use HH\Lib\Vec;
/
- Tを型パラメータとして取り、任意のエンティティを安全に扱う
/
interface IRepository
public function findById(int $id): ?T;
}
// 具体的な実装例
class UserRepo implements IRepository
public function findById(int $id): ?User {
// データベースアクセス…
return new User($id, ‘LegendaryDev’);
}
}
ここが重要だ:
もしここで `User` 以外の型を返そうとすれば、HHVMはコンパイルすら通さない。テストコードを書く時間を大幅に削減できる理由はここにある。実行時に型チェックをする必要はない。型はコンパイル時に消滅し、パフォーマンスへのオーバーヘッドはゼロだ。
—
3. 非同期API連携を制する:`Awaitable` の真価
Webエンジニアにとって、非同期処理は避けて通れない。Hackの `Awaitable
use HH\Lib\Async;
// APIからデータを取得する堅牢なパターン
async function fetchSecureData
$response = await \HH\Asio\curl_exec($endpoint);
// ここでJSONデコードと型検証(shapeやclassの検査)を行う
return validate_as_type
}
この設計の強みは、呼び出し側で「何が返ってくるか」が完全に保証される点だ。`Awaitable` をネストさせても型が崩れない。これがプロダクションコードにおける「予測可能性」だ。
—
4. パフォーマンスの注意点:型消去の理解
HackのGenericsは型消去(Type Erasure)方式を採用している。つまり、実行時のHHVMバイトコード内では、`T` はただのポインタとして扱われる。
- メリット: `List
` も `List ` も同じバイナリを共有する。メモリ効率が極めて高い。 - 注意点: 実行時に `T` の型情報を動的に取り出すことはできない。もし実行時に型を判定したい場合は、`is` 演算子と `shape` を組み合わせるか、`TypeAssert` ライブラリの活用を検討すべきだ。
—
5. 明日からのリファクタリング戦略
PHPコードをHackへ移行する際は、以下のステップを厳守せよ。
1. 境界線に型を敷く: まずは関数のシグネチャに Generics を適用する。`mixed` を撲滅せよ。
2. HSL(Hack Standard Library)に頼る: `array` 関数ではなく `Vec`, `Dict`, `Keyset` を使え。これらはGenericsと完璧に統合されており、PHPの配列のような「連想配列かリストか不明なブラックボックス」を排除できる。
3. Shapeを活用する: DTOを作るほどではない小さなデータ構造は、`shape(…)` を使え。GenericsとShapeを組み合わせることで、型安全性を維持したまま、爆速でプロトタイプを作成できる。
結論
HackのGenericsは、ただの「型付け」ではない。君たちが書くコードの「論理的な構造」をHHVMに証明させるための言語だ。
型エラーは敵ではない。それは、君たちの設計ミスを本番環境に出る前に教えてくれる「最強のレビューアー」だ。怖れるな。Genericsを使いこなし、システムの冗長性を殺し、堅牢なコードベースを築き上げろ。
コードレビューで「なぜ型を使わない?」と聞く側になれ。それが、エンジニアとしての次のステージだ。