【入門編】Strict Modeにおける『null』の排除:Maybeモナド的思考をHackで実装する – Hack言語 コア・静的型システムとHHVMのアーキテクチャ解析バイブル

こんにちは!フルスタックエンジニアの先輩です。今日は、Hack言語における「型」の真髄、そしてHHVM(HipHop Virtual Machine)の圧倒的なパフォーマンスを支える「Strict Mode(厳格モード)」と、nullがもたらす悪夢からの脱却についてお話ししますね。

他の言語(PHPやJavaScriptなど)からHackの世界に入ってきた開発者が、まず最初に直面するのが「`null`の壁」です。
「あれ? さっきまで動いていたコードが、突然型チェッカーに怒られた……」
そんな経験はありませんか?

ここをクリアすれば、あなたの書くコードの安全性とパフォーマンスは劇的に跳ね上がります。さあ、一緒にHackの深淵を覗いてみましょう!

—

1. なぜHackのStrict Modeでは `null` が嫌われるのか?

世のプログラミング言語の多くは、変数が「値を持っているか、あるいは空(`null`)か」を曖昧に扱ってきました。これが、いわゆる 「The Billion-Dollar Mistake(10億ドルの間違い)」 と呼ばれる `null` 参照問題です。

[普通のプログラミング言語の世界]
変数 ──> [ 値 or null (?) ] ==> 実行時エラーの爆弾を抱えている状態

HHVMの静的型チェッカー(`hh_client`)は、コンパイル(正確には型チェック)の時点でこの爆弾を完全に排除しようとします。Strict Mode(`<<__Strict__>>`)では、型が曖昧なコードは一切コンパイルを通りません。

「じゃあ、値が存在するかどうかわからないときはどう書けばいいの?」
そこで登場するのが、関数型言語でおなじみの Maybeモナド的思考(Option型) です。Hackの堅牢な型システムを使って、これを美しく再現してみましょう。

—

2. 許されない `null` と、エレガントな `Option`

まずは、初学者がやってしまいがちなアンチパターンから見ていきますね。

❌ やってはいけないアンチパターン(Nullableの乱用)

<<__Strict__>>
namespace HackGuide\AntiPattern;

// ユーザーIDからユーザー名を引く関数(見つからないと null を返す)
function find_username(int $id): ?string {
if ($id === 1) {
return “Alice”;
}
return null; // うわっ、nullが出てきた!
}

function render_profile(int $id): void {
$name = find_username($id);

// 型チェッカーをパスするために毎回 null チェックが必要に……
if ($name !== null) {
echo “Welcome, ” . $name;
} else {
echo “User not found.”;
}
}

このコード、一見普通に見えますが、Strict Modeではスケーラブルではありません。コードベースが大きくなるにつれ、あちこちに `if ($val !== null)` というボイラープレート(定型コード)が蔓延し、メンテンス地獄に陥ります。

—

⭕ Hack流:Maybeモナド(Option型)による極上の設計

値が存在するかもしれないし、しないかもしれない。その「状態」を一つのコンテナ(型)で包み込んでしまうのが、Maybeモナド的アプローチです。

Hackでは、ジェネリクス(総称型)を使って、次のようにエレガントに表現できます。

<<__Strict__>>
namespace HackGuide\Monad;

// 値の有無をカプセル化する Option 型の定義
enum OptionType: string {
Some = ‘SOME’;
None = ‘NONE’;
}

// データの有無を表現するイミュータブルなコンテナ
final class Option {
private function __construct(
private ?T $value,
private OptionType $type,
) {}

// 値が存在する場合のファクトリー
public static function of(T $value): this {
return new self($value, OptionType::Some);
}

// 値が存在しない場合のファクトリー
public static function none(): this {
return new self(null, OptionType::None);
}

// 値が存在するかどうか
public function isSome(): bool {
return $this->type === OptionType::Some;
}

// 安全に値を取り出す(デフォルト値付き)
public function unwrapOr(T $default): T {
if ($this->type === OptionType::Some) {
// HHVMの型チェッカーに向けたアサーション
invariant($this->value !== null, “Value must exist for Some”);
return $this->value;
}
return $default;
}

// 関数型アプローチ:値が存在すれば変換する
public function map((function(T): U) $f): Option {
if ($this->type === OptionType::Some) {
invariant($this->value !== null, “Value must exist for Some”);
return Option::of($f($this->value));
}
return Option::none();
}
}

—

3. 実践:Option型を使ったモダンなHackコード

先ほどのユーザー検索を、この `Option` を使って書き換えてみましょう。ここからがHackの真骨頂です。

<<__Strict__>>
namespace HackGuide\Practice;

use namespace HackGuide\Monad\Option;

// 戻り値が ?string ではなく、明示的な Option になる
function find_username(int $id): Option {
if ($id === 1) {
return Option::of(“Alice”);
}
return Option::none(); // nullではなく、明確な「無」を返す
}

function render_profile(int $id): void {
$nameOption = find_username($id);

// map と unwrapOr を使って、nullチェックの分岐を排除!
$displayName = $nameOption
->map($name ==> “Welcome, ” . $name)
->unwrapOr(“User not found.”);

echo $displayName . “\n”;
}

<<__EntryPoint>>
function main(): void {
render_profile(1); // 出力: Welcome, Alice
render_profile(99); // 出力: User not found.
}

このコードの何が素晴らしいのか?

1. 実行時エラーの完全な封殺: コードのどこにも `null` が存在しません。そのため、HHVMが実行時に「Call to a member function… on null」のような致命的な例外を吐く余地が1ミリもなくなります。
2. 型チェッカーとの信頼関係: `hh_client` は、コンパイル時に全ての型のフローを追跡するため、バグが混入した瞬間に赤線を引いて教えてくれます。

—

4. 陥りやすい文法エラーと先輩からのアドバイス

HackのStrict Modeを触り始めると、必ずと言っていいほど次のようなエラーに遭遇します。

> Type Checker Error: `Invalid argument` または `Aismung of null`

もし型チェッカーに怒られたら、以下のポイントをチェックしてください。

  • `?T`(Nullable)を安易に使っていないか?

どうしてもデータベースのドライバ層などで `null` を受け取らざるを得ない場合を除き、ビジネスロジック層では `?T` の使用を禁止ルールにしてみましょう。コードの美しさが劇的に変わります。

  • `invariant()` や型ガードを活用しているか?

外部ライブラリとの境界線などで `null` が入り込む場合は、必ず早い段階で `invariant($val !== null, “Error message”);` を使って、型チェッカーに「この先は絶対にnullではない」ことを教えてあげてください。

—

まとめ

今回は、Hack言語のStrict Modeにおける `null` の排除と、Maybeモナド(Option型)的思考による設計について解説しました。

ここをクリアすれば、Hackの基本はバッチリマスターできたも同然です!
HHVMの爆発的な速度と、厳格な型システムがもたらす「絶対に壊れない安心感」を武器に、ぜひ最高でモダンなアプリケーションを構築してくださいね。

それでは、次のハッキングでお会いしましょう!

タイトルとURLをコピーしました