この記事はPhil Freeman, "Why You Should Use PureScript"の邦訳です。この記事の原著者のフィルさんは、PureScriptのオリジナルの作者さんでもあります。原著はCC BY-NC-SA 3.0でライセンスされており、その許諾に従って私が勝手に翻訳・公開するものです。もし翻訳された内容に誤りなどがあれば、修正しますので私までご連絡ください。また、わりとざっくりした記事なので、HaskellやPureScriptについて知識がないとわかりにくい部分もあるかもしれませんが、ご了承ください。これは私の夏休みの自由研究です。みなさんも夏休みの自由研究にPureScriptはいかがでしょうか。
なぜPureScriptを使うべきか
優れた抽象
PureScriptは『型クラス』を持ち、私たちはこれを使ってとても再利用性の高いコードを書いています。PureScriptを使って記述量を減らし、コードの再利用性を更に高めることができます。
あなたは自分が型クラスのない言語で今まで何度traverse
を書いてきたと思いますか?traverse
の実装はNPMライブラリ全体で一度だけされていれば十分です。以下のすべてが同じTraversable
インスタンスによって実現されます。
- リストに入ったAJAXリクエストすべての完了を待つ
- リストに入った複数のフォームフィールドを検証する
- リストに入ったNullになりうる値について、すべてがNullでないことを確認する
- リストに入った複数の値があり、それらに何らかの関数を適用したときの値のうち、最大のものを探索する
ここでもし私が『リスト』という単語を、『ストリーム』、『配列』、『木』のどれかに置き換えたとしても、同じようにtraverse
を使い続けることができます。これらの構造はすべて、同じ型クラスを実装しているからです!
高カインド多相(higher kinded polymorphism)や型クラスがない言語では、コンテナとApplicative
の組み合わせにそれぞれについて、毎回traverse
を書かなくてはなりません。いったい幾つの関数を書くことになるのでしょう! PureScriptではその代わりに、それぞれのコンテナについてtraverse
を一度だけ書き、型クラスを使って形式的に扱います。
優れた抽象は、より一般的な手段を表現し、概念を抽象的に説明できるようにもします。
優れたライブラリ
Pursuitは、あらゆる種類の開発で役に立つ、大量のPureScriptライブラリのドキュメントをホストしています。
- シングルページアプリケーション
- ウェブサービス
- サーバサイドレンダリング
- データベースアプリケーション
- モバイル開発
- テストとベンチマーク
- 画像と音声
- ゲーム開発
- データ構造とアルゴリズム
Pursuitにはありとあらゆるライブラリが揃っています。もし求めているライブラリにぴったりくるものがないのであれば、外部関数インターフェイスを使って、NPMにあるJavaScriptのライブラリをラップして使うことが簡単にできます!
より強力な保証
JavaScriptでは、コードの振る舞いに保証はほとんどありません。たとえば、以下の様なことを確認するのは難しいです。
- データは正しい形式なのか
- 値は
null
でないのか - 正しい箇所で例外を扱っているか
- 製品としてデプロイするまえに、デバッギングコードを取り除いているか
- 複雑なパターンマッチングで、すべての可能性を網羅しているか
- 可変のデータ構造への参照が漏れていないか
- SQLインジェクション攻撃を回避する適切な手順が取られているか
- アプリケーションがうっかりミサイルを発射してしまわないか
PureScriptの型システムは、これらすべてのバグはもとより、さまざまなバグを確実に防ぐ手段を与えてくれます。
優れたレコード
拡張可能レコード1はJavaScriptにとてもよく適していますが、もしJavaScriptのよくあるイディオムが使えないとしたら、それは使いにくくなってしまうでしょう。
PureScriptでは、レコードをマップしたり、トラバースしたり、レコードどうしをマージしたり、ZIPしたり、というようなよくあるパターン2を、まったく型安全に表現することができます。
レコードのラベルについて抽象化することもできます。型システムを使ってレコードのプロパティのLensを自動的に導出することができるので、同じようなLensを何度も書くことはありません。
優れたツール
PureScriptは即時再ビルド(instant rebuilds)を提供しており、エディタ上でコンパイルエラーを即座に確認することができます3。また、エディタのプラグインで、警告を自動的に修正したり、インポート一覧を自動的に最小化したりすることもできます。
『型』を作業にも役立てましょう!型に基づいた検索 (Type-directed search)は、型の情報を利用して、コードの隙間に適合するプログラムを自動的に発見してくれます。
コンパイラにコードを書かせましょう。PureScriptは たくさんの よくある 型 クラスについて、インスタンスを自動で導出することができます。導出がもし提供されていなければ、実装を埋めるのにgeneric derivingを使える場面がよくあります。
優れた手法
Haskellによって開拓された様々なパラダイムを、PureScriptでも数多く提供しています。たとえば、
- データ型に基づくジェネリックプログラミング
- 関数的従属性(functional dependencies)による型レベルプログラミング
- 性質に基づいたテスト(Property-based testing)
- 表示的意味論による設計(Denotational design)
PureScriptは最新の手法を実装した優れた言語でもあるのです。
PureScriptはプログラミング言語の新しい機能についてのアイデアを試すための絶好の遊び場にもなっています。もしJavaScriptがターゲットではないアイデアを試したいと思うなら、コンパイラの異なるバックエンドをご自分でビルドすることもできます。
素晴らしいコミュニティ
SlackやReddit、IRCなどで、静的型付けされた純粋関数型プログラミング言語をウェブブラウザの世界へ導入することに期待している仲間たちを探してみましょう。
よくある不満点
『コードの共有が難しい』4
これは以前は確かにそうだったのですが、現在ではpurescript-bridge
やservant-purescript
といった優れた手段が存在しています。
データ型についてのジェネリックプログラミングは、JSON直列化のような最も重要なものを含む、データ型の共有について書く必要があるコードのほとんどについて、自動導出をとても容易にしてくれます。
『正格評価がデフォルトなのが良くない』
これは興味深い不満点です。私は毎日Haskellを使っており、遅延性を大規模に利用しています。Haskellのような言語の遅延評価の落とし穴について書かれた、素晴らしい投稿もインターネットにはいろいろあります(これとか)。
私が思うに、正格な言語であるかのようにHaskellを使うことが間違いであるように(『スペースリーク』はこういう間違いの典型です)、遅延評価の言語であるかのようにPureScriptを使うのが間違いなのです。
HaskellコードをそのままPureScriptに持ってきて、それがそのまま動くというようには、考えてはいけないということです。もしかしたら動くかも知れませんが、遅いかも知れませんし、ループにはまり込んでクラッシュしたり、そもそもコンパイルできないかも知れません。
しかし、正格な言語における純粋な関数型プログラミングを支援する優れたツールがあります。まったく新しいものもありますし、Scalaのような他の正格な関数型言語で開拓されたテクニックからアイデアを得たものもあります。
究極的には、遅延評価がデフォルトであることの利点のすべてが欲しいなら、GHSJSを使ったほうがいいでしょう。でも、ほとんどの場合は、正格評価がデフォルトの言語で、必要に応じて遅延評価を導入したほうが、ずっと実用的な選択肢になることに留意してください。
『技術者を雇うのが難しい』
Haskellのコミュニティは、これが間違いであることを裏付けています。リモートでPureScript開発者を雇用すれば(そしてもし必要なら研修を気前よく実施すれば)、条件に見合う就職希望者が不足することはないでしょう。
別の言い方をすれば、外部関数インターフェイスを学び、既存のJavaScriptコードへと統合しすることで、PureScriptを段階的に導入することもできます。そのため、多少の関数型プログラミングの経験があるJavaScript開発者を雇い、既存のコードをだんだんとPureScriptへと移行させることでPureScriptの利点を享受することができます。
『学習が難しい』
PureScriptを学ぶのは決して簡単なことではありませんが、十分に可能なことです。少し時間はかかります。
他の人へ教えるというのもまた別の難しさがあり、それもまた多くの時間がかかるでしょう。
もしHaskellや純粋関数型プログラミングに詳しくないのであれば、まずはHaskellの本を通じて学ぶのをお勧めします。それから、PureScriptの本へと進み、PureScriptのコードの振る舞いについての考え方を理解するために、Puresuitにある中核ライブラリのドキュメントを読んだりするといいでしょう。
『圏論はもうたくさんだ』
PureScriptの習熟にあたって圏論についての知識は必要ありませんが、中核ライブラリの更なる深淵へと辿り着くときの助けにはなるのは間違いありません。圏論を修得するというのは、長期的な投資です。
もし理論的基礎を学ぶことに興味あるのであれば、計算機科学者向けか何かの標準的な圏論の教科書の、最初の章を読んでみることをお勧めします。
『サポートが不足している』
まあ要するに、PureScriptコンパイラの開発にお金を出してくれるひとがいないということです。これはいつか変わることがあるかもしれませんが、今のところは長期間のサポートを期待するのは無理です。PureScriptは他のオープンソースライブラリと同じように扱うのをお勧めします。
まあそうは言っても、でももしあなたがどうしてももっと良いサポートを必要としているのであれば、小銭と交換でってことになるかも知れませんね。
『ドキュメントが足りない』
高品質なドキュメントを提供しようと最善を尽くしていますが、複雑な考え方をわかりやすく説明するのは難しい問題ではあります。
プルリクエストは歓迎です! もしドキュメントを改善する方法について何かアイデアがあれば、ぜひ教えて下さい。でも、もしFunctor
をMappable
に改名するつもりはないと私たちが言ったとしても、どうか落ち着いてください。
『PureScriptは変更が早過ぎる』
PureScriptは1.0に到達するまでは破壊的変更が続くでしょうが、このマイルストーンはかなり近づいています。いろいろと安定してきていますし、0.12.0から1.0までは破壊的変更はあまり多くないと思います。
『Bowerは好きじゃない』
Bowerを使っているのには幾つかの理由があり、それについてはハリーさんが詳細に書いてくれています。BowerがJavaScriptに適するかどうかはともかく、それでもPureScriptにはぴったりと適しているのです。
でも、Bowerを使わなければならないというわけではありません。psc-package
とPurifyという代替のパッケージマネージャがすでに存在しています。
PureScriptでNixを使う人や、Gitを直接使っている人もいます。PureScriptは特定のパッケージマネージャへ依存しているわけではありません。
『Nodeを使いたくない』
前項をご覧ください。特にpsc-package
とPurifyはNodeには依存していません。
REPLについては、Nodeを使う代わりに、ブラウザで--port
オプションを使って評価することもできます。
-
訳注・ここでいう『レコード』とは、JavaScriptのプレーンなオブジェクトに相当するものです。Haskellにはない機能ですが、PureScriptではJavaScriptとの親和性を高めるために採用されており、JavaScriptと同じように
foo.bar
というような構文でレコードのプロパティにアクセスできます。 ↩ -
訳注・要するに、
Object.keys
でオブジェクトのプロパティ名を列挙して反復するとか、そういうメタ的な操作がPureScriptでも型安全にできるということです。最近になって型レベルプログラミングの機能が揃うまでは、こうした操作は難しい部分がありました。 ↩ -
訳注・編集があった特定のソースファイルのみを再ビルドすることで、コンパイルエラーを瞬時に確認することができるということです ↩