PureScriptはJavaScriptにコンパイルする,強い静的型付けを持った言語だ。 Haskellに影響され,Haskellで記述されたこの言語は,"非常に表現力のあるコードが記述可能でありながら",JavaScriptへの変換後も"クリアで可読性のよい"ことを目標としている。さらに,作者のPhil Freeman氏によれば,JavaScriptをターゲットとする他の言語との相互運用性も提供する。
PureScriptの特徴的な機能のいくつかは,Haskellから継承されたものだ。すなわち,
- 型推論: 可能なすべての場所で,具体的な型を推定することができる。
- 高階(Higher Kinded)ポリモーフィズム: モナド(monad)およびDSLに不可欠な型コンストラクタ上の抽象化メカニズム。
- パターンマッチング: 実装を複数のケースに分割することで,複雑な関数のコンパクトな記述を可能にするテクニック。
- 型クラス: データ自体の構造について直接考慮することなく,データ構造体を使用可能にする抽象化メカニズム。
PureScriptのもうひとつの強みとして氏が主張するのが,相互運用性だ。PureScriptには,JavaScriptの値や関数のための型が用意されている。通常のPureScriptコード内でそれらの関数を使うことにより,既存のJavaScriptコードをインポートすることができる。これによってPureScriptをアプリケーションの一部でのみ使用して,その他の部分をJavaScriptあるいはその類型の言語で記述することも可能だ。
InfoQではFreeman氏に,言語の詳細について聞いた。
PureScrptを開発することになったプロセスについて教えてください。おもな動機と目標は何だったのでしょう?
開発を始めたのは1年程前です。当時私は,中程度の規模のJavaScriptアプリケーションに取り組んでいました。それをTypeScriptで書き直したのです。ほとんどの場面において,TypeScriptは非常に生産的だったのですが,もっと強力な型システムがあれば,と思ったアプリケーションの一部がありました。その頃にも,もっと表現力のある型システムを持った言語はたくさんありました。ですが,私が必要としていた他の機能との組み合わせを提供してくれるものは,ひとつもなかったのです。具体的に言うと,クリーンで可読性のよいJavaScriptを生成してくれて,ランタイムシステムを必要としない,Haskellライクな構文の言語が欲しかったのです。自分自身でコンパイラを書こうとしていたのなら,言語をHaskellで設計したでしょう。ですが私は,Haskellのシンプルな部分だけを使ってPureScriptを実装することにしました。その方が,コンパイラ開発者の興味を引くと思ったからです。その点に関しては,プロジェクトは成功を収めています。PureScriptには現在,すばらしい開発者コミュニティがありますから。
PureScriptの中心的な機能は何ですか?
シンプルなFFI,表現力のある型システム,予測可能なコード生成です。簡単に言えば,PureScriptは"原則に基づいたJavaScriptを書くための,より良い環境"を提供するのです。
一般的なJavaScript開発に対して,PureScriptが持っているメリットを簡単に説明して頂けますか?
最も大きな利点のひとつは,大規模なコードベースでも,既存の機能を損なうことなく,自信を持ってリファクタリングできることです。純粋な関数プログラミング - 純粋関数,不変データ構造,明示的な副作用など - を使うと決心すれば,コンパイラの支援を受けながら,極めてアグレッシブにコードをリファクタすることができます。もうひとつは型システムの表現力ですね。既存のJavaScriptのツールでは難しい,プログラムの特質を明確にするような記述が可能になります。例えば"correct-by-construction"のデータ構造 - バランスの保証されたバイナリツリー,プロパティの妥当性が保証されたHTMLノードなど - を持った,ドメイン固有言語を作ることもできます。さらにこれを,特定のIDEに依存することなく,移植性のある方法で実現することが可能なのです。そして最後に,PureScriptのような言語では,パラメトリックなポリモーフィズム,高階関数や型クラスといったものを利用して,他の言語では実現できないような強力な抽象化が可能です。
PureScriptは型推論や型クラスなど,いくつかの機能をHaskellから受け継いでいますが,2つの言語の違いはどのようなところにあるのでしょう?
簡単に言うとPureScriptは,構文の面ではHaskellにかなりよく似ていますが,セマンティクスが違います。これはPureScriptが,JavaScriptのセマンティクスを使っているからです。例えば,PureScriprtが行う評価は,Haskellと違って厳密です。またPureScriptは,個々の関数レベルでは末尾呼出最適化(tail-call optimization)のみを行うので,Haskellのコードで一般的なイディオム(モナド再帰がその一例です)を使用する場合には,スタックオーバーフローの検出が重要になります。型システムにもいくつか,重要な違いがあります。 PureScriptには,Haskellの影響を受けたすばらしい機能(マルチパラメータ型クラス,ランクN型(rank-N type)など)がありますが,HaskellにあってPureScriptにはない機能もたくさんあります(型ファミリ,Polykinds,Datakindsなど)し,HaskellにはないPureScript独自の機能もあります(拡張可能なレコードや拡張可能なEffect)。
[UHC]や[ghcjs]など,JavaScriptにコンパイルされる他のHaskellライクな言語と比較した場合,PureScriptをどう思われますか?
FayやHaste,GHCJSなど,HaskellライクなAltJS(JavaScript代替)言語の多くは,Haskellのある種のサブセットを,Haskellのセマンティクスを保持しながらJavaScriptにコンパイルする手段を取っています。既存のHaskellコードの大部分をJavaScriptコードとして再利用できますから,これはとてもパワフルなアイデアです。PureScriptはHaskellのサブセットではありませんし,セマンティクスもJavaScriptのものを使用しています。ですがPureScriptには,FFIがとても使いやすい,というメリットがあります。そのおかげで,NPMパッケージマネージャによって提供されるような,既存のJavaScriptライブラリと,簡単に統合することができるのです。このことは,2つの開発スタイルが大きく異なる理由となっています。PureScriptのスピリットには,RoyやJMacroといった言語に近いものがあります。実際にRoyは,PureScriptのデザインに大きな影響を与えました。Haskellライクな言語としては,Elmも興味深いですね。Elmは,インタラクティブなWebアプリケーションの実装に純粋関数プログラミング,関数型のリアクティブプログラミングのテクニックを採用しているのです。
PureScriptが今後目指す方向について,あなたの考えを簡単に説明して頂けますか?ロードマップはどのようになっているのでしょう?
今のところは,次のリリースのコンパイラとツールに注力しています。うまくいけば,主要な3プラットフォーム用にバイナリを準備できると思います。コンパイラの自己ホストバージョンの開発にも,かなりの時間を費やしています。"npm install purescript"を使ってコンパイラをインストールできるようになるとよいですね。次のリリースが終わったら,興味深い機能をたくさん考えています。少し挙げただけでも,型ワイルドカード,テンプレートによるメタプログラミング,イディオムブラケットなどがあります。新たなバックエンドについても関心があります。つい最近はLunaバックエンドを新たに加えました。Pythonバックエンドの実現性についても,議論を行ってきています。もちろん,ライブラリやツールの開発テーマも尽きることはありません。開発者コミュニティは大歓迎です。コントリビュートを希望する方は,Freenodeの#purescript IRCチャネルをチェックして頂ければと思います。
PureScriptはオープンソースプロジェクトだが,Linux用にはビルド済みバイナリも用意されている。PureScriptを始めるには,Phil Freeman氏による "LeanPub book" と,インストール不要で言語を体験できる "Try PureScript webpage" という,2つの優れたリソースがある。