標高+1m

Don't be rational.

ソフトウェアのバグがなくならないならユーザを全員プログラマにすればいい

f:id:ympbyc:20140202122436j:plain

ソフトウェアのバグについて。バグをなくすかユーザをプログラマ*1にするか。

テストについて

テストを手で書いて、全ての手続きについてソフトウェアが実行時に取り得る全ての状態のもと*2で正しい結果を返すことを保証するには時間もお金もかかりすぎる。

Haskellではテスト書かなくていいみたいなことを言っているのをたまに見るけど、コンパイル時に見つかるバグが多いってだけで、型だけ合っててもしょうがないことはかなりある。

Coqみたいなので依存型を駆使してプログラムの正しさを証明するか、多少の妥協は許すとしてQuickCheck的なことをするかってことをしないなら、プロダクション環境でバグが出るということを前提にソフトウェアを作るというのも手かもしれない

Smalltalk

Smalltalkのソフトウェア開発は、ソースの入力から中間言語への翻訳から実行まで全てがSmalltalk環境というソフトウェアのランタイム上で行われる。Smalltalkで作るソフトウェアは実質的にSmalltalk環境の拡張として作られ、ソフトウェアのユーザはこの拡張が適用されたSmalltalk環境を走らせる。

実行環境と開発環境が一緒になっていると、以下のようなシナリオが展開されるかもしれない。

ソフトウェア(=拡張)を作る人をDさん、ソフトウェアのユーザをUさんとする。

f:id:ympbyc:20140202093643p:plain

Dさんは、ユーザからの入力を受け取って、その入力の結果をもとに一連の処理を行う、ひどく単純な計算機プログラムを作った。

f:id:ympbyc:20140202104041p:plain

Dさんはdivide: x by: 0という式を入力としたテストを書き忘れてしまい、そのままこのソフトウェアを公開してしまった。

Uさんはこの計算機プログラムを手に入れ、しばらく便利に使っていたが、あるときdivide: 2 by: 0と入力してみた。

f:id:ympbyc:20140202104634p:plain

するとランタイムエラーZeroDivideが発生したことを告げるポップアップが現れた。Uさんは、Debugと書かれたボタンを見つけてクリックしてみた。

f:id:ympbyc:20140202105416p:plain

CalculatorSampleクラスのdivide:by:メソッドが呼ばれて、その中のxに対する/ yというメッセージ送信の時にエラーが起きたことがわかったUさんは、divide:by:メソッドを修正して、yが0だったらエラー文言を表示するようにした。

f:id:ympbyc:20140202115045p:plain

結果、UさんはDさんが作った計算機を便利に使えるようになり、末永く幸せに暮らした。

こういうことは実は結構頻繁にある。例えばSmalltalk環境用のパッケージマネージャーみたいなのでインストールした拡張を動かすとエラーが出て、2行くらい修正したら動いたとか。

こういうことができると、ある機能がある条件で使えないという小さな問題のためにソフトウェアそのものを諦めずに済むから良い。そしてバグは踏んだら踏んだときに直せばいいやと気楽な気持ちになる。

ユーザがプログラマならバグがあってもいい -- crowd debugging

Smalltalk環境を持ち出してきたのは単にバグの発見から修正して走らせるまでのサイクルが僕の知る中で一番簡単だから。別にSmalltalkじゃなくてもプログラマならMakeFileを書き換えたりってことはしょっちゅうやっているはず。ユーザがプログラマかつ、デバッグ環境が整っていれば、極論を言えばバグを抱えたままリリースしてもいい。

もちろん実際にやるとしたら、今まで通りテストをして、かつこうした環境を用意してやるということになるとは思う。

プログラマじゃなくてもデバッグできるかもしれない

とは言っても現実には、コンピュータユーザ全員をプログラマにするという夢は実現しそうにない。なら逆にプログラマじゃなくてもデバッグできる環境を作ればいいかもしれない。絶対難しいけど、研究してみると面白そう。

ではでは

*1:この記事ではプログラマという言葉をプログラムを書ける人という意味で使う

*2:OOみたいに状態が散らばってると本当にヤバい