この記事は、「プログラマが知るべき97のこと」について、英語と日本語訳を記載したものです。
プログラマが知るべき97のこと(オライリー・ジャパン、2010年)
Kevlin Henney(編)、和田 卓人(監修)、夏目 大(訳)
各エッセイはCC-by-3.0-USによってライセンスされています。
Functional programming has recently enjoyed renewed interest from the mainstream programming community.
最近プログラミングコミュニティでは、再び関数型プログラミングへの関心が高まっています。
Part of the reason is because emergent properties of the functional paradigm are well positioned to address the challenges posed by our industry’s shift toward multi-core.
その理由としては、業界全体でマルチコアヘの移行が進んでいる、ということもあるでしょう。移行によって生じる新たな課題への対処に、関数型パラダイムの持つ特性がうまく合致することが明らかになってきたからです。
However, while that is certainly an important application, it is not the reason this piece admonishes you to know thy functional programming.
確かにそれも重要な理由です。しかし、仮にそれだけなら、私がここでわざわざ「あなたも関数型プログラミングを学ぶべき」という文章を書くこともなかったと思います。
Mastery of the functional programming paradigm can greatly improve the quality of the code you write in other contexts.
関数型プログラミングのパラダイムを十分に学べば、その知識、技術は、マルチコアヘの対応以外にも幅広く役立つでしょう。まず、自分の書くコードの品質を大きく高めることができます。
If you deeply understand and apply the functional paradigm, your designs will exhibit a much higher degree of referential transparency.
重要なのは、参照透過性(referential transparency)が向上するということです。
Referential transparency is a very desirable property: It implies that functions consistently yield the same results given the same input, irrespective of where and when they are invoked.
参照透過性が高い、というのは非常に素晴らしいことです。参照透過性が高いとは、関数がどこでいつ呼び出されようと、入力が同じであれば、常に得られる結果が同じになる、ということを意味します。
That is, function evaluation depends less — ideally, not at all — on the side effects of mutable state.
つまり、関数の評価結果が状態変化の副作用に左右されることが少ない(あるいは、まったくない)ということです。
A leading cause of defects in imperative code is attributable to mutable variables.
手続き型プログラミングに不具合が生じる原因となりやすいのが、「可変(mutable)な変数」です。
Everyone reading this will have investigated why some value is not as expected in a particular situation.
本書の読者なら、ある変数の値が、状況によって予期したとおりにならず、その理由を調べた経験が少なからずあるでしょう。
Visibility semantics can help to mitigate these insidious defects, or at least to drastically narrow down their location, but their true culprit may in fact be the providence of designs that employ inordinate mutability.
「可視性セマンティクス(visibility semantics)」などが、そうした目に見えにくい不具合を減らす上で役立つことはありますし、少なくとも、不具合の箇所の絞り込みにかなり役立つのは間違いないでしょう。しかし、ここで本当に問題なのは、そもそも、変数の値が変わってしまうような設計をしてしまったことです。
And we certainly don’t get much help from industry in this regard.
そういう設計を防ぐために参考になるものは、業界全体を見渡してもあまり見つからないことは確かです。
Introductions to object orientation tacitly promote such design, because they often show examples composed of graphs of relatively long-lived objects that happily call mutator methods on each other, which can be dangerous.
オブジェクト指向言語の入門書などには、変数の値が変わる設計を、暗黙のうちに助長してしまっているものもあります。比較的「長生き」するオブジェクトたちが、互いの値や状態を変えるメソッド(mutator methods)を次々に呼び出す、というようなプログラム例が図解入りで載っていたりするからです。これはとても危険です。
However, with astute test-driven design, particularly when being sure to “Mock Roles, not Objects”, unnecessary mutability can be designed away.
しかし、適切なテスト駆動設計をすれば、特に「オブジェクトではなく、ロールのモックを作成すること」を心がけるようにすれば、不要な可変性は、設計から排除できるでしょう。
The net result is a design that typically has better responsibility allocation with more numerous, smaller functions that act on arguments passed into them, rather than referencing mutable member variables.
大事なことは、可変なメンバー変数の参照が必要になるような設計をしないことです。それよりも、小さな関数を数多く作り、個々の役割を限定する方が得策です。個々の関数は、自らに渡される引数にのみ作用するようにします。
There will be fewer defects, and furthermore they will often be simpler to debug, because it is easier to locate where a rogue value is introduced in these designs than to otherwise deduce the particular context that results in an erroneous assignment.
そうすれば不具合は減り、おそらくデバッグも簡単になるでしょう。この設計では、仮に変数に不適切な値が入ったとしても、その箇所を特定するのが容易になるからです。そうでない設計では、不適切な代入がどのようなコンテキストで行われたかを推測する、ということまで必要になるおそれがあります。
This adds up to a much higher degree of referential transparency, and positively nothing will get these ideas as deeply into your bones as learning a functional programming language, where this model of computation is the norm.
このように参照透過性を高めることは非常に大切なのですが、それを血肉となるくらい深く理解するには、やはり関数型プログラミング言語を学ぶのが一番でしょう。関数型の言語では、参照透過性の高いプログラムを書くのがごく当たり前のことだからです。
Of course, this approach is not optimal in all situations.
もちろん、参照透過性を高めることがどんな状況でも好ましいというわけではありません。
For example, in object-oriented systems this style often yields better results with domain model development (i.e., where collaborations serve to break down the complexity of business rules) than with user-interface development.
参照透過性を高めるようなスタイルは、オブジェクト指向システムの場合、ユーザインターフェース開発よりも、たとえばドメインモデル開発において(つまり、コラボレーションがビジネスルールの複雑さの低減に役立つような場合に)好結果につながりやすいようです。
Master the functional programming paradigm so you are able to judiciously apply the lessons learned to other domains.
関数型プログラミングのパラダイムについてよく学ぶことで、関数型言語での開発以外の場面にも、学んだことをうまく応用できるようになるでしょう。
Your object systems (for one) will resonate with referential transparency goodness and be much closer to their functional counterparts than many would have you believe.
オブジェクト指向システムであっても、参照透過性を高めることができれば、利益は大きいはずです。一般に信じられているよりも、オブジェクト指向システムと関数型システムの間に違いはありません。
In fact, some would even assert that the apex of functional programming and object orientation are merely a reflection of each other, a form of computational yin and yang.
中には、「突き詰めれば、関数型プログラミングとオブジェクト指向プログラミングは、どちらもお互いの鏡像にすぎない」などと言う人もいます。「陰と陽」のような関係、と言ってもいいかもしれません。
By Edward Garson