⚠️

コンパイルエラーはコンパイルエラーではない

2023/02/12に公開

エッセイ記事です。Twitterで以下のようなツイートが回ってきました。

このツイートは、「やさしさ」という代替案の冗談っぽさに反して、筆者には非常に本質的で示唆に富んでいる指摘に思えたので、それについて記事を書いてみます。

「エラー」という語の印象

確かに、「エラー」は一般的には「本来出るべきではないもの」という印象があるため、いくらその道のエキスパートが「コンパイルエラーは実行時のエラーを防ぐためのありがたいものである」と唱えても、「エラー」と呼ばれている以上は、それが画面上に表示されて確認できること自体を忌避してしまう、という条件付けのようなものが人々の心理に働くのは自然なことです。

コンパイラーからすれば、この手の「エラー」はほぼ確実に致命的なものであることがわかっている[1]ため、「エラー」という語の持つ迫真性を以てユーザーにその危険性を伝えることは妥当かもしれません。大抵の場合は[2]ユーザーの入力(コード)に問題があることは事実なので、ユーザーは問題をしっかりと認識しなければいけません。しかし、問題を伝えられたときに、その内容よりも形式に影響されやすいユーザー[3]の目には、往々にして大量に赤くハイライト表示されたりする「エラー」メッセージは、ややもすると自分が怒られているかのように映るのであり、そのような迫真性のせいでコンパイラーからのアドバイスが忌避されるようになったり、問題の対処をはかるユーザーの気力が削がれたりするようでは、誰も幸せになりません。

コンパイルエラーはコンパイルエラーではない

ここで筆者が思い当たったのは、コンパイルエラー自体はエラーではないのではないか、というアイデアです。そもそも一般に「コンパイルエラー」と呼ばれているものは、「コンパイル対象のソフトウェアの、(そのまま誤ってコンパイルを通してしまえば)実行時に起こりかねないエラーの予測」であって、「コンパイラーの、コンパイルという仕事におけるエラー」ではないはずです。むしろコンパイラーとしては、それが検出されたらコンパイルを通さない、ということの方が正しい挙動なのであり、このこと自体は本質的には決してエラーなんかではありません。どちらかと言えば、実行時にバグるような誤ったソフトウェアのコンパイルを通してしまうことの方が、コンパイルエラーと呼ばれるべきものです

したがって、冒頭のツイートの話に戻るのですが、筆者としては「コンパイルエラー」を「エラー」と呼ばずに何か別の言い方をした方が良いという発想は完全に理に適っていると思いました。「コンパイラーのやさしさ」という冗談めかした代替案は面白いですが一発ネタ感があり[4]、個人的にはこの話をもう少し真剣に考えているので、現実的な落とし所を見つけたいところです。

代替案

「コンパイラーのやさしさ」という言葉の意味しうるところには若干の曖昧さがあります。例えば、我々の意図するところとは逆に「コードに瑕疵があるのに、コンパイラーにお目溢しをもらってコンパイルを通してもらう」といったような、この世の終わりのような状況も「コンパイラーのやさしさ」と言えないこともないでしょう。もちろん、本当はそれは「やさしさ」などではなく単なるネグレクトです。「コンパイラーがやさしく教えてくれる」といったようなイメージの湧く言い回しが望ましいです。

  • コンパイルレポート
  • コンパイルサポート
  • コンパイルアドバイス
  • コンパイルトレーニング
  • コンパイルケア

適当にいくつか考えたのですが、個人的にしっくり来ると思うのは「コンパイルケア」です。これは特に「ネグレクト」の対義語として考えたもので、「コンパイラーが「エラー」を出してくれないことはネグレクトである」というアイデアを入門者に伝えるのにも役立つ気がしていますし、「実行時に起こりうるエラーをコンパイラーが心配する(care)」という実情にも即しています。

筆者は今後は「コンパイルケア」と呼んでいくことにしました。前述したような迫真性は失われてしまう気がしますが、個人的には、もはやそれを「コンパイルエラー」と呼ぶことは正しくないのでやめたい、という動機の方が優ります。


草草


追伸: JAXAのロケットのアナロジー

この記事を発表した直後(といっても数日後ですが)、JAXAの新型ロケット「H3」が発射できなかったのは「中止」か「失敗」かという話題が俗世に発生しました。あまりに似通った話なので、これについて追記します。

このロケット打ち上げ停止が中止なのか失敗なのかという不毛な[5]論点に対する筆者個人の所感は「その両方である」です。というのも、すでに巷で散々言われていることではありますが、これはプロジェクトマネジメント上の短期的な視点からは残念な失敗であり、かつ、打ち上げシステムの設計の視点からは失敗ではなく安心安全な中止だからです。「どちらなのか」という議論はシンプルに不毛であり、ここでは重要ではありません。

筆者が取り上げたいのは、ロケット打ち上げの話と、この記事の話とのアナロジーです。「ロケット」は「コンパイル対象のソフトウェア」、「打ち上げシステム」は「コンパイラー」に対応すると自然に考えることができます。打ち上げプロジェクト(ソフトウェア開発)達成の成否と、打ち上げシステム(コンパイラー)設計の成否は直交していますし、時間スケールも異なります。

例えば、長期的な視点で見れば、件のロケット発射が中止されたとはいえ次回に持ち越されただけであるのと同じように、あなたのソフトウェアのコンパイルが一度止まったということが、ただちにそのソフトウェア開発プロジェクトが失敗したことを意味するわけではありません。また、そのときコンパイルが止まったことによって、あなたのソフトウェアのドメインモデルやアルゴリズムにおける問題点に気づくことができ、プロジェクトが成功に近づくこともあるかもしれません。余談ですが、コンパイラーとしては、そのような理解につながる建設的な指摘となるようコンパイルケアを与える努力をするのが理想ですし、コンパイラー利用者としては、貧弱なコンパイルケアからでもそのような理解を得られるように努力するのが良い習慣です。

このような類推からわかるように、「コンパイルエラー」を「コンパイルエラー」と呼ぶことは、ロケット発射が安心安全に停止したことを「打ち上げエラー」と呼ぶようなものです。それは本当に打ち上げという仕事におけるエラーでしょうか? 打ち上げに際して本来可能な問題把握や検査を放棄し、将来的に事故を発生させることがわかっているロケットを打ち上げることの方が、「打ち上げエラー」と呼ぶべきなのではないでしょうか。そう考えると、「コンパイルエラー」がいかに胡乱な言い回しであるかがわかると思います。

脚注
  1. コンパイル対象のソフトウェアの実行時に何か大変なことが起こる予兆である ↩︎

  2. コンパイラーにバグがあったり、その部分の型システムに完全性(正しいプログラムならば必ず型が付くもしくは型チェックが通る、という性質のこと)がなかったりするのでなければ ↩︎

  3. これは人間に広く共有された特質なので、つまりほぼすべてのユーザー ↩︎

  4. おそらくご本人もそういうノリでツイートされたのだろうと推察します(違ったらすみません) ↩︎

  5. 本来複数ある視点(評価軸)を混同することに基づく、という意味で ↩︎

Discussion