業界動向

経営のトピックス-PR-

第1回 関数型プログラミングの世界へようこそ

2006/08/02
ITpro

 Haskellというプログラミング言語を知っていますか?

 全く聞いたことがないという人が多いかもしれません。そういう名前の言語があるのは知っているけど,どんな言語かは知らないという人もいるかもしれませんね。でも最近では,一部の先進的なソフトウエア開発者の間で,一種のブームと言えるほど熱狂的に受け入れられています。

 なぜならば,Haskellは様々な優れた特徴を持っているからです。最初に,他の言語にはあまり見られない際だった特長を一つだけ紹介してみましょう。「遅延評価(lazy evaluation,怠惰評価ともいう)」です。

 遅延評価とは,与えられた値を必要になるまで評価(計算)しないということです。この性質により,不必要な計算が行われる無駄をなくすことができます。また,「潜在的に無限の大きさを持つデータ構造」といった通常のプログラミング言語では扱いの難しいものを直接扱えるため,より直接的な形でプログラムを記述できます。

 このように「何らかの処理を遅延させて必要な部分だけ行う」といったやり方は,一般的なコンピュータの世界,あるいは現実の世界でも広く行われています。例えば,コンピュータ・グラフィックス(CG)では,画面に現れなかったり画面に影響を与えなかったりする部分を計算(レンダリング)しないことにより,計算時間の無駄を省く手法がよく用いられます。また,プログラムの実行時にすべての機能をあらかじめ呼び出しておくのではなく,必要になるまでオブジェクトの生成やデータの取得などを保留することで,プログラムの起動の高速化を図る手法もよく利用されています。現実世界の例としては,必要なものを必要なときに必要なだけ生産することによって仕掛在庫を抑える「カンバン方式」(ジャストインタイム生産方式)が挙げられます。

 Haskellの遅延評価を実感してもらうために,簡単なコードの例を見てみましょう。今は雰囲気さえつかめれば完全に理解できなくてもかまいません。以下のコードは「ある関数fをn回適用する関数」であるrepeatedを定義するためのコードです。

 repeated f n = \x -> (iterate f x)!!n

 まず,iterateという関数を使って[(f x), (f (f x)), (f (f (f x))), ...]というようにxに関数fを重ねて適用していった結果を際限なくリストとして並べています。このリストの中から,!!という演算子を使ってn番目の結果を取り出しています。つまり,いったん無限の長さのものを用意しておいて,そこから必要なものだけを取り出すという記述になっています。

 繰り返し処理を行っているのに関数の中に終了条件がないことに不安を覚える人がいるかもしれません。通常のプログラミング言語では,終了条件がなければ無限の処理が行われる,つまり無限ループになります。しかし,「必要になった時に必要なだけ評価する」という遅延評価のおかげで,ループや再帰などを使って明示的に終了条件を提示しなくても,このコードはきちんと終了します。n番目の値を取り出すために必要となるn回の処理しか行われないことが保証されているのです。こんな簡単な例でも,Haskellが持つ高い能力の一端を実感できますね。

日本語の解説書の出版が相次ぐ

 私自身がHaskellの学習を始めたのは2002年です。書籍「達人プログラマー」(ピアソン・エデュケーション発行)に書かれている「毎年少なくとも一つの言語を学習しよう」という話をもとに提唱された「The "Language of the Year" project」で,2002年の言語として選ばれたのがHaskellだったからです。

 一般的に注目されるようになったのは,解説書が相次いで出版された影響が大きいでしょう。2006月3月には向井淳氏が執筆した「入門Haskell―はじめて学ぶ関数型言語」(毎日コミュニケーションズ発行),6月には青木峰郎氏が執筆した「ふつうのHaskellプログラミング ふつうのプログラマのための関数型言語入門」(ソフトバンク クリエイティブ発行)と日本語で書かれた入門書が立て続けに発売されました。「入門Haskell」は,ページ数の制約から学習曲線が急になってしまっている印象があるので,とりあえず最初の1冊を選ぶとすれば「ふつうのHaskellプログラミング」が良いでしょう。とはいえ,この本が取り上げているトピックは十分に広いとはいえないので,余裕があるなら「入門Haskell」も読んでみるといいかもしれません。

 雑誌では,情報処理学会会誌の「情報処理」で2005年4月から2006年3月までの1年間,「Haskellプログラミング」という記事が連載されていました。この記事は現在,Webで読むことができます(参考リンク)。また,日経ソフトウエア2006年6月号の「プロのソフト技術者になるためのプログラミング実力アップ大作戦」という特集には,酒井政裕氏が執筆した「Haskellによる関数型プログラミング入門」という記事が掲載されています。

 Haskellはイベントでも注目を集めています。2006年3月に東京で開催されたPerl関連イベント「YAPC::Asia 2006 Tokyo」では,HaskellによるPerl6の実装であるPugsの開発者であるAudrey Tang氏が,Pugsについての講演とHaskell入門の講演を行いました。これを聞いてHaskellのすごさに目覚めた方もいるかもしれません。

 最近は様々な人がHaskellを勉強し,その様子をWeb日記やブログに書くようになりました。さらに,「ふつうのHaskellプログラミング」を対象にした読書会もいくつか開催されています。参加者の中には,「はじめて学習するプログラミング言語がHaskell」という人もいるようです。

アプリケーションの開発にも使われている

 アプリケーション開発にHaskellを用いている人達もいます。Haskellで実装された有名なアプリケーションとしては,HaskellによるPerl6の実装であるPugsがあります。また,Pugsに比べると若干,知名度は落ちますが,分散バージョン管理システムのdarcsもHaskellで書かれています。日本では,Haskellを使ってゲームのグラディウスを実装したMonadiusが2005年6月頃に注目を集めました。

 大学などの研究機関のみならず,一般の企業で実際の仕事にHaskellを用いている人たちもいるようです。Haskellのサイトにはそうした企業が求人広告を出しているページがあります。Haskellに関係した論文の執筆者の所属には,研究機関や米海軍艦隊計算機気象海洋学センター(FNMOC:Fleet Numerical Meteorology and Oceanography Center)のような軍関係に加え,一般の企業の名前も見られます。

 Haskellの持つ機能の強力さに引かれ,そうした機能を他の言語に取り入れようとする試みもあります。例えば,C++やJavaのライブラリの中には,Haskell風の関数型プログラミング(functional programming,関数プログラミングともいう)をサポートしたり,そうして実現したHaskell風のコードを内部実装に使用しているものがいくつか現れてきています。また,C#の次のバージョンであるC# 3.0(およびVBの次期バージョンであるVB 9)やC#を拡張した研究用の言語であるCω(Comega)は,言語の新しい機能として,Haskellをはじめとする関数型言語から様々なアイディアを流用しています。

Haskellを動かすための処理系

 Haskellにはいくつもの処理系があります(参考リンク)。どれを使えばいいか迷うかもしれませんが,比較的安定したメジャーな処理系であるGHC(The Glasgow Haskell Compiler)Hugsを選べば,まず問題はありません。ただし,インストールやパッケージなどについて若干注意したほうがよい点があります。

 GHCはコンパイラを基本としているため,それ自身がHaskellを使用して書かれています。このため,GHCのビルドにはあらかじめGHCが必要になります。また,GHCのビルドには長い時間がかかります。下手に自分でビルドしようと色気を出さず,すでに提供されているパッケージをダウンロードしたほうがよいと思います。Windows用にはstandaloneとVisual Studio version(Visual Haskell)の2種類が提供されています。ただ,Visual Studio versionは問題が多いので,使わないほうが無難です。Windows用standaloneの最新バージョンは6.4.2です。

 Mac OS X版は,Power PC搭載のMacの場合には一つ前のバージョン(6.4.1)が提供されているので,それを使うのがよいと思います(参考リンク)。インストーラーを含むGHC-6.4.1.pkg.zipを使うのが一番楽でしょう。実はDarwinPortsで最新版が提供されているのですが,DarwinPortsの知識が必要になります。問題も若干,報告されています(参考リンク)。Intel Macの場合には,6.5のバイナリが提供されています(参考リンク)。ただ,開発版であることに注意してください。このバージョンを使う場合には,Webページの最初に挙げてあるバイナリ(現在はghc-6.5.20060608.tar.bz2)を利用するのが一番手軽です。ただし,GUIのインストーラは存在しないため,configureやmake installといったコマンドを使ってインストールする必要があります。

 もう一つの処理系であるHugsは,Cで書かれたインタプリタだけの処理系なので,そんなに気構えなくても自分でソースからビルドすることもできます(いくつかのツールを使用する場合はビルドにGHCが必要になります)。注意点は,最新版のバイナリでは,Windows版のインストーラがmsiパッケージではなくなっていることです。アンインストーラの定義がXML(eXtensible Markup Language)で書かれているため,Windows XPより前のWindowsでは素直にアンインストールできなくなっています。この問題が気になる方は,「The Haskell School of Expression: Learning Functional Programming through Multimedia」(SOE)という本のサポート・サイトで提供されている少し古いバイナリを使うとよいと思います。

この連載が目指すこと

 Haskellは,関数型プログラミングというジャンルに属する言語です。Haskellや関数型プログラミングを題材に物事を見ていくことで,今まで思いもよらなかったような未知の世界を知ることができるでしょう。

 ただし,ある言語の基本的な文法やプログラミング・スタイルを身につけることは,その言語を学ぶことの一部でしかありません。それ以上の考え方を知りたければ,領域ごとに人々の知恵の集積によってつちかわれてきたものも知らなければなりません。入門段階を終えた先にも,ある言語を通して学べることはたくさんあります。これらは,単に言語を使用したり学習するだけで身につきません。プログラミング言語を学ぶという行為には,

  1. 言語の基本的な文法や考え方を理解する
  2. 言語の文化圏で広く使われている考え方に親しんでその言語らしい書き方を習得する
  3. 単に言語を使ってできること以上の知恵を学ぶ

の3段階があります。この連載では,三つ目の段階を目標に,Haskellプログラミングの世界を一つひとつ丁寧に紹介していきたいと思います。

 ただ,「単に言語を使ってできること以上の知恵を学ぶ」といっても,具体的なイメージがつかめないかもしれません。例としては,前に述べたように,C++やJavaにHaskell風の関数型プログラミングを導入するライブラリがあります。ライブラリ・レベルで別のパラダイムを実現してしまうものです。例えば,Prologで行うような論理型プログラミング(logic programming)を可能にするライブラリ,1から6の起こる確率がそれぞれ約16.7%といったように確率的な値を使って計算を行う確率的関数プログラミング(probabilistic functional programming)を実現するライブラリ,音楽記述言語やアニメーション記述言語のようなある特定の分野で使われる専用の言語―DSL(Domain Specific Language,特定領域言語,ドメイン特化言語)を言語内(internal,embedded)で表現したりするようなライブラリなどが挙げられます。また,論理型プログラミングや確率的関数プログラミングがわかる人なら容易に想像できるように,近い将来,量子計算を表現するライブラリなども出てくるかもしれません(参考リンク)。

 少し難しすぎたでしょうか。未知の単語との遭遇にとまどった人は少なくないと思いますが,ここで述べているような例はこの連載を通して適宜説明していくつもりです。今は「いろいろとすごいことができるらしい」というぐらいにとらえていただければ十分です。

 最後にこの連載のタイトルの由来を紹介しておきましょう。「本物のプログラマはHaskellを使う」というタイトルは「本物のプログラマはFORTRANを使う」や「本物のプログラマはPascalを使わない」といった有名なフレーズをもじったものです。この言葉の意味は,出典元である「The Real Programmer Stories」(本物のプログラマ)という文章(日本語訳)やウィキペディア(Wikipedia)の解説などを見てください。

洋書の入門書について

 日本語の解説書が発売される前は,洋書の入門書を読む必要がありました。日本語の解説書が出た今となっては不要に思えるかもしれませんが,そんなことはありません。洋書の入門書は,最近出た日本語の本とは異なり発売時期が早いため,最近の話題は全く扱っていませんが,その代わりに日本語の本よりも高度なトピックを扱っています。意欲のある人はステップアップのために日本語の本の次に読むと良いと思います。

 洋書の入門書の定番は3冊あります。すでに名前の出た「The Haskell School of Expression: Learning Functional Programming through Multimedia」(SOE)のほかに,「Introduction to Functional Programming using Haskell second edition」(IFPH)や「Haskell: the Craft of Functional Programming second edition」があります。IFPHは武市正人先生の訳した「関数プログラミング」(近代科学社発行)の第2版にあたる書籍で,その後,Haskellの時代になって取り入れられた機能や概念などを使って書き直されています。広範なトピックを扱っており,章末に発展的な勉強をするための文献案内も用意されています。ただ,Haskellの仕様で使われているASCII文字ではなく,その文字の由来となった数学の記号を用いてコードを記述しているので,そこがよくないと思う人もいるようです(ちなみに,GHC6.5ではそうした記号を用いてコードを書けるようにするための拡張が取り入れられています)。「Haskell: the Craft of Functional Programming second edition」は,まさに教科書といった感じの本です。新しい物事を学ぶ度に何度も同じ問題に立ち戻ってくる懇切丁寧な解説が魅力です。

 SOEはグラフィックスなどのマルチメディア処理を通してHaskellプログラミングを学ぼうというコンセプトの入門書です。DSLなどのトピックにも触れている意欲的な本です。しかしながら前2冊に比べて薄いため,Haskellや関数プログラミングなどについての説明があっさりしすぎているという欠点があります。この本だけではHaskellを使えるようになるのは難しいでしょう。ただ,他の本を読んだあとに読むといろいろな発見のある本だと思います。2冊目3冊目に読む本としてはよいかもしれません。

 SOEのサンプル・コードを試す場合,前に示したサポート・サイトで公開されているHugsを使うのが一番手軽です。最新版のGHCやHugsにはGraphics.SOEという名前でSOEのグラフィックスに関するコードを利用するためのモジュールが入っており,これを使ってみようと考える人がいるかもしれませんが,いくつか注意が必要です。まず,モジュール名がSOEGraphicsではなくGraphics.SOEになっていることからわかる通り,SOEのグラフィックス・ライブラリおよびそれが利用しているHGL(Haskell Graphics Library)というパッケージに含まれるモジュールの名前などがSOEのものから変更されています。このため,若干コードを変更する必要があります。また,Windows版のGHCやHugsも含まれているHGLは,一部機能を除いてきちんと動かないという問題があります(参考リンク)。WindowsでSOEのサンプル・コードを試したい場合には,必ずサポート・サイトで公開されているバージョンのHugsを使ってください。

著者紹介 shelarcy

 フリーのプログラマ。東京経済大学経営学部卒。人生を変えてしまった最初のきっかけがプログラミングとの出会いならば,それを決定的なものにしてしまったのはHaskellとの出会いかもしれません。いつもは,Haskellのライブラリを作ったり,Haskellでアプリケーションを作ったり,はたまた海外の方が作って公開しているライブラリやアプリケーションの開発を手伝ったりと,Haskell漬けの日々を送っています。ただ今,Haskellのことをやって暮らしていけるようになるために画策中。

http://page.freett.com/shelarcy/

  • このエントリーをはてなブックマークに追加
  • Evernoteでクリップする
  • 印刷する

今週のトピックス-PR-

この記事に対するfacebookコメント

nikkeibpITpro

▲ ページトップ

CIO Computerworld

Twitterもチェック