実用期を迎えた関数プログラミング 参加レポート

実用期を迎えた関数プログラミング 参加レポート
LITERAL-ICE 林政利

私は長らくJavaなどの命令型言語でプログラマーをやっていますが、昨今はScalaを通して「関数プログラミング」の名前自体は良く聞くようになってきています。
とはいえ、関数型というパラダイム自体は、「長らくコンピュータサイエンスの研究領域にあると思われていた関数プログラミング〜”(本セミナーの紹介文より)とのお言葉どおり、業務等での採用事例は多くないだろうと思っていました。
そういうわけで、関数プログラミングの経験、知識はほとんどありません。
そんな中、「実用期を迎えた関数プログラミング」と刺激的なコピーもあり、本セミナーの参加に踏み切ることにしました。
セッションの内容が完全に理解できたわけではありませんが、印象に残ったポイントをレポートしたいと思います。

「関数プログラミングのエッセンスと考え方」
小笠原 啓さん(ITプランニング)

現在、業務でもOCamlを使っているという、ITプランニングの小笠原啓さんによるセッションです。
関数プログラミングを採用すると、そうでない場合に比べてどういうメリットがあるのか……その疑問を解消すべく拝聴しました。

・採用事例の紹介

まずは、採用事例の紹介から。

・金融関係、プライベートファンドのトレーディングシステム
・計量的金融(クォンツ)のシステム
・COBOLコードの解析
・仕様の記述
・Xenの管理ツール
・等々

様々な事例があるようですが、主に金融関係の分野やソースコードなどの解析処理に使われてきたようです。

小笠原さんによると、関数プログラミングのメリットの一つは、「複雑な処理を簡潔に書ける」こと。
つまり、アルゴリズムを簡潔に書くことができ、複雑なロジックや、パーサーなどを書くのに向いているということでした。
この特徴から、仕様記述などのDSLや、ソースコードの解析プログラム、金融取引のビジネスロジックを記述しやすくなるようです。

さらに、TwitterでScalaが採用されていること、関数型言語を使ったWebフレームワークなどの事例も紹介されました。

「近年は、Web系のサービスも品質の高いものが素早くリリースされるようになってきており、不具合のあるものをとりあえず出してみて……といった開発は通用しにくくなっている」
品質の高いものを、素早くリリースすることが求められている、とのことです。確かにそのとおりだと感じています。
そのためには、静的な型付けが一助になるということで、型を重視するものが多い関数型言語はその点でも有利なようです。
関数型言語には静的な型がないものもあると思いますが、関数プログラミングを実践するには型があったほうがやりやすい、ということでしょうか。

小笠原さんのところでも、金融チャートの作成やサーバーサイドの処理にOCamlを使用していて、さらにブラウザ上での表示に用いるJavascriptもOCamlで記述しているのだとか。
ocamljsというソフトで、OCamlソースをJavascriptにコンパイルできるらしいです。
Javascriptにコンパイルできるツールというと、CoffeeScriptや、Javaから変換できるGWTが有名ですが、OCamlにもあったとは驚きました。
Javascriptをそのまま書く場合に比べて、コンパイル時の型チェックを受けられたりなど、品質の向上が期待できますね。

・関数プログラミングの機能、特徴の紹介

この後、関数プログラミングで使われる様々な機能、特徴の紹介がありました。

・関数を受け取る関数、高階関数でリストのソート方法などを柔軟に指定する。
・リソースのオープン・クローズ関数とリソース内容の処理をする関数を分けるローンパターンにより、ファイルポインタなどをエレガントに取り扱う。
・等々

このあたりは、関数オブジェクトやクロージャのある言語なら関数型言語でなくとも実現できるな、後で質問してみよう……と思いながら聞いていましたが、
コーディング例など、具体的な内容に触れるうちに、どうやらそういうレベルではないらしい、ということが分かってきます。
つまり、関数プログラミングを快適に実践するには、関数を変数に格納できるという程度では不十分だということです。
関数プログラミングを支援する言語機能として、以下のようなものが紹介されました。

・関数を変数に格納でき、さらに無名でも定義できること
・関数内部が静的なスコープを持つこと
・関数の引数の一部だけを変数にバインドした別関数を返す部分適用を簡単に利用できること
・変数は上書きしない。配列、リストの中身も書き換えない

これらの機能は、関数を頻繁に定義し、それをいろいろな場所に渡して使用する以上ないと困るし、変数が上書きされたり副作用があると関数を組み合わせて使用することが難しくなるのだろう、と私は理解しました。

個々の要素、例えば高階関数や部分適用などのみに注目して他言語、JavaScriptやRubyなどを見ていけば、これらの機能を備えた命令型言語はたくさんあると思います。
実際、関数を使ったプログラミングもできると思うのですが、やはり型や変数の取り扱い、副作用をどのように扱うか、スコープや値の評価方法など、関数型言語としてデザインされた言語でなければ、関数プログラマーの方々がおっしゃるレベルの関数プログラミングは実現できないのだろうと感じました。

・関数型言語に備わる便利機能

・代数的データ型

関数型言語には、その他にも便利な機能が備わっているようです。
一例として、「代数的データ型」の紹介がありました。
様々な型を格納できる、共用体のような特別な型ですが、「パターンマッチ」と呼ばれる機能を使えばその共用体に何の型が入っているのか簡単にチェックできるようです。
これらを使って正しい型に対してプログラミングすることで、安全な処理が可能だということでした。

・形式手法

小笠原さんのセッションで一番興味深く感じたのが、この形式手法のお話でした。
「形式手法」とは、数学的な手法で開発を支援する一連の取り組みのことで、これを用いると、「プログラムが正しいことを数学的に証明する」ことなどが可能なのだとか。
現在広く行われている品質確保手段であるテスティングでは、あくまで有限数の入力に対する出力を見ることしかできないのに対して、この形式手法を使えば無限のパターンに対して証明という形で品質の確保ができるというのです。
そして、変数の書き換え、副作用を排除した関数型言語は、この形式手法ととても相性がいいらしい。
小笠原さんの所属するITプランニングは、実際にこの「形式手法」を業務に取り入れておられるということで、既にそこまで実用的なレベルにあるのかと、とても感銘を受けました。

関数プログラミングを実践することで、プログラムの書き方が変わるだけでなく、新しい開発手法、コーディングの概念を業務に取り入れることができるかもしれない。
全体を拝聴して、特に形式手法のお話でそのことを良く実感できたと思います。

パネルディスカッション「実用期を迎えた関数プログラミング」
小笠原 啓さん(ITプランニング)
酒匂 寛さん(デザイナーズデン)
水島 宏太さん(日本Scalaユーザーズグループ,株式会社ユビレジ)
山本 和彦さん(IIJイノベーションインスティテュート)

第二部のパネルディスカッションでは、関数プログラミングを日々使用しておられる方々から、関数プログラミングの様々な側面についてのお話を聞くことができました。

・山本 和彦さん(IIJイノベーションインスティテュート)

山本さんからは、Haskellのお話を拝聴しました。
HaskellのWebフレームワークYesodについてはこのフォーラムで初めて知ったわけですが、普段Web関係の仕事をしているため、このフレームワークの話はとても印象に残りました。

・Haskellは、コンパイルが通れば大体思い通りにプログラムが動く
・HaskellのWebフレームワークであるYesodは、コンパイルが通れば大体思い通りにWebアプリが動く
・型安全URL。コンパイルできればアプリ内でのリンク切れが発生しない
・型を利用したセキュリティ対策。コンパイルできればXSSが発生しない
・話題のnode.jsより数段高速に動く

どの特徴も、刺激的で魅力的なものばかりです。
速度については、Yesodや、Yesodを乗せるHTTPサーバーWarpで様々な高速化対策が施されているようです。
文字列連結の際に計算量を減らす、HTTPリクエストをイベントループと軽量スレッドで処理する、その際カーネルになるべくアクセスしないようにするなど。
このWebフレームワークとサーバーのお話を聞いただけでもHaskellを学習したいという気持ちが大きく膨らみました。

・水島 宏太さん(日本Scalaユーザーズグループ,株式会社ユビレジ)

Scalaは、JVMで動作し静的な型付けを持つプログラミング言語です。
Javaで仕事をすることが多い私はよく名前を聞く言語ですし、実際に少し使ってみたこともあります。
関数型言語して使用できますが、Scalaのパラダイムは関数型に限られているわけではなく、ベターJavaとして書くことも可能です。既存のJavaのクラスライブラリもそのまま使用できます。
水島さんのセッションでは、Scalaの事例紹介を中心に、実際にどのようにScalaを使用できるのかといったお話を聞くことができました。

ScalaはTwitter社がよく使っていることで有名で、水島さんにより次のような事例が示されました。
・Github上のTwitterのリポジトリは半分近くScala
・EffectiveScalaと題してコーディング規約などを公開→Scalaは既に実験的な段階ではなくて、業務使用上のノウハウや規約がまとめられる段階にまでなっている
・RPCフレームワークFinagleなどの公開

また、Scalaエコシステムとも言える周辺ツールも数多く紹介されました。
・SBT…ビルドツール。Scalaプロジェクトの多くが基盤にしている
・specs2…BDDフレームワーク。Scalaによるテスト記述
・Lift、Play Framework2…Webフレームワーク

このあたりは、業務でもゲリラ的に使用してみることもできそうだな、と思いました。
また、Scalaの創始者が立ち上げたTypesafe社のサポートもあって、IDEの品質などもぐんぐん良くなってきているらしいですね。

Scalaという言語は、もう本当に身近なものになっているのだなと思わされます。
水島さんによれば、ScalaはJavaをやってきた人よりもRubyなどに親しんできた人の方が取っつきやすいらしい、とのことですが、それでもやはりJavaのプログラマーが関数型を学ぶならScalaが一番始めやすいのではないかという印象を受けました。

・酒匂 寛さん(デザイナーズデン)

酒匂さんからは、仕様記述言語VDM++と、その中での関数型言語機能についてのセッションです。
VDM++については名前くらいしか聞いたことがなかったので、大変勉強になりました。
VDM++は、仕様を関数という形で記述し、その仕様の事前条件、事後条件も定義することができる言語のようです。
そうすることで、仕様に矛盾、バグがないか、早い段階からテストやデバッグで確認することができるわけですね。
私はJavaのアサートやEiffelの表明を書きながらのプログラミングをイメージしましたが、普通の言語と異なり、まだ仕様が決まっていないところはTBDとして残したまま記述していくことも可能なようです。

VDM++では、副作用のある処理とない処理を分けて記述することができ、副作用のない関数部分については関数型言語的な側面を持ちます。
特に面白いと感じたのは、
・実装をどのように行うにせよ、事前条件や事後条件などの仕様だけは関数で書くことができる
・さらに、今までエクセルに列挙していたような用語集を仕様として関数の形で蓄積しておけば、仕様を書く際に楽ができる

関数は副作用がなく、単独で見て理解しやすいはずなので、そういったことがやりやすいのだろうと理解しました。
このような使用方法なら、開発を今まで通り行うにせよ、仕様書の記述のみにVDM++を取り入れる、ということもできそうな気がします。

・まとめ

セッションを聞き終えて感じたことは、関数プログラミングを深くやり込んだプログラマーと、Javaなど命令プログラミングの経験しかないプログラマーとでは、見えている世界が全然違うんだな、ということです。
関数プログラミングを勉強することで、関数の再利用方法や型に対する考え方、開発手法などに新しい風を入れることができそうだと思いました。
さらに、Webアプリケーションなど、業務に近い部分にも既に取り入れられているとなれば、関数プログラミングを学習しないわけにはいきませんね。
帰って早速「ふつうのHaskellプログラミング」を購入しましたので、これをきっかけに関数プログラミングを身につけていこうと思います。
この度は貴重なセッションをお聞かせいただき、本当にありがとうございました。