関数型言語に関して思うこと

ここ最近というわけではないが,関数型言語に関する話題をよく目にするようになったような気がする.何を持ってして関数型言語であるかというのは非常に悩ましい問題ではあるが,おそらく最も古くに生み出された関数型言語がLispであろうことを考えれば,関数型言語の歴史は非常に古い.それに対して,世の中のコンピュータの基盤であるOSなどの低レイヤを支えるc言語がLispより20年近くあとに生み出されたことを考えれば,c言語やその影響を受けた後続の言語(JavaやLLなど)がいかに新しいかがわかるはずだ.

私はもともとc言語からプログラミングを入門し,次にC++を学び,Java,Pythonと進めてきた.特にC++に触れてきた時間は非常に長く,プログラミングの思考回路がC++をもとに組み上がっていると言っても過言ではない.したがって,初めて関数型言語に触れたときは強い隔たりを感じた.特に違和感を感じたのは,関数型言語の記述がアセンブリから完全に乖離している点だった.CやC++などの手続き型言語が,何をしたいのかを書くのに対して,関数型言語が何が成り立つのかを書くというのはよく言われる話だが,コンピュータの根幹をなすアセンブリ言語が前者の立場にあることを考えれば,関数型言語がそのままの形では全く相容れないことは明らかである.

ではなぜそのような関数型言語が今になって注目されているのだろうか.その一つの答えは,関数型言語を支える非常に強力な仕組みである型システムが,プログラムの記述を簡単にし,更にはバグさえも防ぎ得るということにあるではないだろうか.そもそもc言語やそこから派生した言語は,人間がミスをすると簡単にバグが挿入される可能性がある.これは例えれば鋭いナイフのようなもので,その切れ味をうまく活かせれば大抵のことは効率よく行うことができるが,使い方を誤れば自身を傷つけてしまう諸刃の剣となる.これはc言語の前身であるB言語の更に前身であるBCPLの哲学である

BCPLの哲学は、最良を知ると皆が考える暴君がいるのではなく、何が許されて何が許されないのかという決まりが定められているのでもない。どちらかといえばBCPLは、たとえ明らかに馬鹿げた事態に直面したときでさえ、不平を言わずに自らの能力を最大限に活かしてサービスを提供せんとする召使いとして振舞う。彼が何をしていて、細かい制限に制約されないということを、プログラマーは常に理解しているものと考える。
「BCPL, the language and its compiler」より

にあらわれている.これはプログラマが過ちを侵さないという絶対の信頼のもとで成り立っている.しかし,実際にはそのようなことは絶対にありえない.むしろ世の中にこれほど人為的ミスとしてのバグがはびこっているのは,人間がそこまで賢くないことを示唆しているのではなかろうか.

さて,人の書くプログラムには絶対にバグが入り込むと考えたとき,これを防ぐためにはどのようにしたら良いだろうか.関数型言語における,この問題に対する答えはバグが入り込む可能性があるような書き方は,そもそも許さないというものである.関数型言語では,関数の副作用を極力許さないことと,型に基づいた統一的な記述により制約をかけている.このような制約は,動的型付けであり副作用がてんこ盛りのLLから見れば,非常に強いものだが,バグを防ぐ上では非常によく機能することがわかっている.

ある言語が,手続き型言語と関数型言語のどちらであるかは程度の問題であって,完全な線引があるわけではない.pythonやperlなどであっても記述の仕方によっては関数型言語のように書くことができるだろうし,LispやOCamlでも手続き型言語のような記述ができるはずである.しかし,言語のサポートによって関数型言語として代表されるような記述がどこまで可能であるかが変わってくる.特に大きな線引は高階関数が扱えるかどうかではないかと思う.関数型言語が特に流行りだした頃から,多くの言語でラムダ式(無名関数)をサポートするようになったが,部分適用が言語レベルでサポートされているのは殆ど見たことがない.しかし,関数型言語にとって高階関数が無くてはならない存在であることを考えれば,これをサポートしていない多くの言語は一般には関数型言語とは呼べないのではないか.

とにかく,高階関数はもちろんとして,完全に純粋すなわち副作用を持たない言語としてHaskellが有名である.Haskellのすごいところは,その徹底ぶりにある.多くの関数型言語は,副作用を全く持たないことを保証できていない.これはおそらく,利便性の観点から完全に副作用を除外すると,非常に書きづらくなる恐れがあるからではないだろうか.画面に文字を表示するということですら,簡約のやり方によっては表示の順番が変わってしまう恐れがあるため,そのままでは副作用は避けられない.しかし,Haskellではモナドを用いることで,理論的にも妥当なやり方で副作用を追いやることに成功している.さらに,Haskellは遅延評価を用いることで便宜的とはいえ,加算無限の概念を記述することも可能である.Haskellのすごいところは,そういった,一見達成困難なことを理論的に美しい方法で,コンピュータ上の実装のレベルまで落とし込んでいる点にある.これにより,Haskellは数学と非常に相性が良い.特に関数型言語の利点である,性質を記述することでプログラムが可能であるという点がうまく引き出されており,これは数学の式の記述に非常に近いものになっている.

ここまで思ったことをつらつら書いてみたが,あまりに何も考えてなさすぎてとりとめのないものになってしまった.とにかく,最後に私が言えることは,関数型言語を全く知らない人はどのようなものかを一度勉強してみるべきだということだ.そこには,手続き型言語だけでは感じることができない,理論によって整理されたきれいな世界が広がっているのだから.

内容についてどう思いますか?
  • いいね (2)
  • だめ (1)

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

CAPTCHA