読者です 読者をやめる 読者になる 読者になる

「美しい,だから正しい」より「正しくて,あわよくば美しい」がよい

関数プログラミング実践入門.発売されました.電子版もあります.


今回は本書の副題に関する話題.本書の副題には「正しい」を使っている.実際に価値を提供するのは「正しい」コードなのだが,プログラミング関連文書でよく目にするコードに対する修飾は「美しい」なのだ.これは何故だろう.

といっても,大抵の人は経験などから「美しい*1」コードならば読み易く間違えにくいということを知っている.なので,この点についてそう深く考える必要は無いようにも思われる.「美しい」コードは善である.

しかし,「正しさ」についてあまりにも「美しさ」に頼るようでは危険だ.「美しいから正しい」ことがわかる状態はつまり「ヒトが目を凝らすから正しい」ことがわかる状態ということに他ならない.ヒトは間違える.目も頭も疲れる.

通常,「美しい」コードに保つのは存外コストを要する作業である.お仕事であればザックリと事業戦略の正しさがまず前提にあって,プログラムが必要となれば次に仕様や設計自体の正しさがきて,その後にコードの正しさが続き,やっと価値を提供できる.そして,コードの「美しさ」は「正しさ」よりもさらに後の話になる.「正しさ」を「美しさ」に頼り過ぎていると,プライオリティ的に「美しさ」が後回しになったとき,必然的に技術的負債としての程度が大きくなる.適度に返済しない限り次なる価値の提供に支障が出易くなる.

また,「美しさ」はその人の背景知識や主観にも強く左右される.ある種の難しい知識を修めた人にとっては良いコードに見え,そうでない人にとってはただ無駄に難解なコードにしか見えないということもある.即ち,「正しさ」を「美しさ」に頼り過ぎていると,全く同じコードベースに対してさえ「正しい」コードを書き易いと感じる人と書き難いと感じる人がいる,などということが起こり得る.ともすると「美しい」コードとは自己満足の「美しさ」でしかないという可能性もある.

コードの「正しさ」はコードの「美しさ」に依存しない程よい.

実際にテストファーストなどは最初に何らかの正しさを定め・コードの質から切り離そうとする行為だし,さらにCIなどではヒトが何度も目を凝らす代わりにjenkinsおじさんとかががんばってくれる.

強く型を付けることもまた正しさを定め・コードの質から切り離そうとする行為だし,こちらでは型検査がヒトが何度も目を凝らす代わりにがんばってくれる.そして,型で表現できる性質に対しては,一般にテストよりも網羅的な検証効果を持つ.もちろん,型で表現できないものも中にはあるだろう.

さらに,強く型を付けられることの延長線上には定理証明がある.ここに至っては「型さえ合って実装できてるなら正しいんだから書かれてるコードは読まない」と言われるほどコードの質に興味を持たれないケースまである.これはこれで過激派過ぎて駄目な面もあるのだが,コードの「正しさ」の保証が強力になるに伴い,「美しさ」含めたコードの質の重要度が相応に低下したこと示す顕著な発言でもある.

他にも,静的・動的解析ツールによるバグの検知はそれだけで商売にもなっている*2HaskellがらみでもLiquidHaskellなどは定めた性質の証明をある程度自動で行ってくれる.

重要なのは「正しさ」のために取れる手段の多様性だ.

「美しさ」を保つのにコストがかかるように「正しさ」を保証するにもコストがかかるし,各手段によって保証できる「正しさ」も度合いが少しずつ異なる.トレードオフは少なからず存在する.

テストは言語に依らず実施可能だが,あまり網羅的な保証することができないし,効率的な自動実施の仕組みも必要となる.強力な型システム上に限られるが,型で表現できる部分はテストよりも網羅的な効果を持ち,検査の仕組みは大抵言語処理系が持っている.定理証明が可能ならば申し分なく強力な保証となるが,証明のための作業コストは馬鹿にならない.自動証明や解析は,可能な範囲や対象言語が限定されるが作業コストはかからない*3

選択した言語・環境に許された手段の中で,直面している問題に対し,どの程度の「正しさ」をどの程度のコストを払って保証したいかによって選択すべき手段が変わる.言語や環境の選択時点で,取れる手段が多様であればトレードオフに合った適切なバランスのものを選択し易い.逆に手段が限られるのは恐しいことだ.本来もっと網羅的な検証を行う価値が認められるクリティカルな項目に対してさえも,テストしか手段が無ければテストにより検証する他ない.


改めて,副題に「美しい」でなく「正しい」を使った.その理由は,ひとつはコードの価値がどちらにあるかと言えば「正しい」であるため.もうひとつは,関数プログラミング及びそれを主目的とした関数型言語達は,その性質の良さから,「美しさ」に依存しない「正しさ」の保証に比較的強みを持たせ易いため.

*1:「整然とした」などのニュアンス含め

*2:Coverity PreventやKlocworkなどが有名なのかな?

*3:金銭コストはかかるかもしれないが