Hack: a new programming language for HHVM – Facebook Engineering

In the hurry? 今すぐ Hack をお試しください。 http://hacklang.org/

本日、私たちが HHVM 用に開発した、PHP とシームレスに相互運用可能なプログラミング言語である Hack をリリースします。 Hack は PHP の高速な開発サイクルと静的型付けによる規律を調和させ、他のモダンなプログラミング言語で一般的に見られる多くの機能を追加します。 昨年、私たちはほぼすべての PHP コードベースを Hack に移行しましたが、これは有機的に採用されたことと、いくつかの自作のリファクタリング ツールのおかげです。

HHVM ランタイム プラットフォームの一部として、Hack のオープン ソース バージョンを http://hacklang.org/ で一般に公開することも誇りに思っています。 上記のコードは、よくある間違いの好例で、メソッドが予期せず null オブジェクト上で呼び出され、実行時まで捕捉されないエラーが発生する可能性があります。 別の例としては、開発者がそのセマンティクスをしっかりと理解していても、ドキュメントでありふれたメソッド名を調べるのに時間を費やしてしまうような複雑な API があります。

Facebook の規模では、何千人ものエンジニアが 1 日に 2 回新しいコードを出荷するので、こうしたスローダウンはさらに問題になってきます。 Hack の前に、私たちは迅速なフィードバック ループを備えたシンプルな言語を持っていましたが、上記のような問題をどのように軽減できるのでしょうか。 エラーの早期発見と高速なイテレーションを共存させ、PHPへの投資を維持することはできないか? コード解析とイントロスペクションの改善により、オートコンプリートのようなツールで開発者の生産性を向上させることができるでしょうか。

伝統的に、動的型付け言語は高速開発を可能にしますが、特に大きなコードベースでは、エラーを早期に発見しコードを迅速にイントロスペクションする能力を犠牲にしています。 逆に、静的型付け言語はよりセーフティ ネットを提供しますが、多くの場合、迅速な反復の代償としています。 私たちは、スイートスポットがあるはずだと信じていました。 私たちは、動的型付け言語と静的型付け言語の両方の長所を提供し、あらゆる規模のプロジェクトで価値があると信じています。 実際、ほとんどの PHP ファイルはすでに有効な Hack ファイルとなっています。 私たちは、一握りの非推奨の関数や静的型付けと互換性のない機能 (たとえば、「変数変数」や extract() 関数) をサポートしないように意識的に選択しました。 また、開発者の生産性を向上させるのに役立つと思われる多くの新機能を追加した。

主な追加機能は静的型付けである。 関数のシグネチャやクラスのメンバに型情報を付与するシステムを開発し、型チェックアルゴリズム(「タイプチェッカ」)が残りを推論する。 型チェックはインクリメンタルに行われ、1つのファイル内でも一部のコードをHackに変換し、残りは動的型付けを維持することが可能である。 技術的に言えば、Hack は “gradually typed*” * 言語であり、動的に型付けされたコードは静的に型付けされたコードとシームレスに相互運用できる。

Hack の型システムにおいて、ジェネリックス、Nullable 型、型エイリアス、型パラメーターに対する制約などいくつかの機能を導入している。 これらの新しい言語機能は控えめであるため、Hack で書いたコードは PHP プログラマーが慣れている動的言語のように見え、感じることができます。 私たちは、静的型付けとジェネリックでうまく動作するように特別に設計しました。 Collections API は、関数型プログラミングを容易にするため、map() や filter() などの多くの古典的な高階関数を提供します。 PHP にもクロージャはありますが、プログラマーは、包含するスコープから使用する必要のある変数を明示的に名付ける必要があります。 Hackのラムダ式では、これらの用途を自動的に推論するので、無駄な作業を省くことができます。 ラムダ式は、Collections API を最大限に活用するのに便利です。

Run-time enforcement of return types and parameter types (including scalar types like int and string) provides safety than what can be checked statically while the type annotations are gradually added to the codebase. ランタイム強制は、プログラマーが特定の種類の問題をより簡単に検出および診断するのを助け、最適化の目的のために型注釈を安全に信頼することにより、HHVM の JIT がより効率的なコードを生成するのを助けます。 エンジニアは必要なだけ素早く反復し、完璧になるまでエクスペリエンスをテストおよび調整できます。

伝統的に、タイプ チェッカーはソース コードを分析するのに時間がかかるため、このフィードバック ループを中断してしまいます。 私たちは PHP のワークフローを遅くしたくなかったので、即時のフィードバックと型の安全性を調和させるための新しいアプローチを考え出しました。 サーバーはソースコードに関するすべての情報をメモリに保持し、ファイルがディスク上で変更されると自動的に自身を更新する。 このアプローチにより、タイプ チェッカーは通常 200 ミリ秒未満で実行され、1 秒以上かかることはほとんどなく、顕著な遅延を発生させずに開発ワークフローに簡単に統合できます。 いくつかのコードをすぐに完全に Hack に移行することは困難であることを理解し、Hack が段階的に導入される際に他の PHP ファイルと直接共存できるように開発されることが重要だった。 たとえば、同じファイルであっても、ある関数では型アノテーションを追加し、別の関数では省くことができる。 関数パラメーターまたはクラス メンバーに明示的な型注釈がない場合、型チェッカーはその型を動的なものとみなし、その値の型をチェックしません。

Facebook 内では、エンジニアが Hack を十分に評価し、彼ら自身のコードの大部分を自発的に変換し始めることがわかりました。 私たちのツリーには何百万行ものコードがあるため、何らかの自動化が必要であり、プロセスを支援する多くのコード修正ツールを構築し使用しています (これらは Hack の一部としてリリースされます)。 実際、私たちは PHP-5 と同等になるよう懸命に取り組んでいます。 HHVM の最優先事項の 1 つは、コミュニティのため、そして内部でサードパーティの PHP ライブラリに依存しているため、修正されていない PHP-5 ソースコードを実行することです。

HVM は現在 PHP と Hack の *both* をサポートするランタイムですので、Hack の新機能を少しずつ利用し始めることができます。 これは最初のステップに過ぎず、私たちはこのソフトウェアを進化させ続け、私たち自身のエンジニアとより広いコミュニティの両方にとって開発をより簡単にすることに専念しています。 Hack の価値は、大きなプロジェクトに限定されるものではありません。型情報、優れたエラー メッセージ、そして迅速なフィードバックにより、小さなコードベースでも Hack の恩恵を受けることができます。

来月、メンロパークの Facebook キャンパスで行われる Hack Developer Day でも言語を紹介しますので、そこで直接またはオンラインでお会いできればと思います。

謝辞

Hack の開発に貢献してくださった多くの方々がいます。

コア Hack チームは Julien Verlaguet, Joel Beales, Eugene Letuchy, Gabriel Levi, Joel Marcey, Erik Meijer, Alok Menghrajani, Bryan O’Sullivan, Drew Paroski, James Pearce, Joel Pobar および Joshua Van Dyke Watzman から構成されています。

言語をより良くするために貴重なフィードバックを提供してくれた、初期のコミュニティ採用者に特別な感謝を捧げます。 James Miller, Simon Welsh, Nils Adermann, Fabien Potencier, and Alexander Mols.

Hack は主に OCaml で書かれています。 OCaml 言語の開発については Gallium チーム (INRIA) に、Ocsigen の js_of_ocaml 部分の開発については Ocsigen チーム (CNRS – University of Paris Diderot – INRIA) に感謝したいと思います。

そしてもちろん、Hack を今日のような言語にしてくれた他のすべての人に感謝します。 このリストはブログの記事にするには多すぎますが、あなたが誰であるかはご存知でしょう

コメントを残す

メールアドレスが公開されることはありません。