たれぱんのびぼーろく

わたしの備忘録、生物学とプログラミングが多いかも

エラーと人とプログラミング

We Want to Write Logics, NOT to Fix Bugs.

But Human make mistakes.

人は間違う、ゆえに動作確認がいる

  1. 人はエラーを起こす
  2. 人はプログラムを書く
  3. ゆえに、プログラムはエラーを起こす

人のおこなった処理はエラーを含む。
エラーを避ける/直すの仕組みが必要である。

エラーを含まないなら、動作確認 (テスト) なんていらない

バグ、エラー
デバッグ
動作確認
テスト

It’s well known that developers make mistakes during design and code. If developers did not make mistakes, they would have no need to test their code.
Physics of Test Driven Development | James Grenning’s Blog

デバッグにかかる時間

プログラミングの多くの時間は、予期しない動作、つまりエラーを取り除くことに使われる(統計が欲しい)。

qiita.com

blog.livedoor.jp

デバッグとは

バグ・欠陥を発見および修正し、動作を仕様通りのものとするための作業である。
デバッグ - Wikipedia

テストってのはバグを発見するためのものだから、デバッグの一環だよな

gihyo.jp

デバッグ 割合
工数 割合

bug injection
td: discover
bug appear
tfind: find the cause
bug find
tfix: bug fixxing
bug fixed

blog.wingman-sw.com

td ~ changed_code
tfind ~ changed_code ~ td

tdの最小化が非常に有効 == バグの早期検出が重要

  • コーディング時 (td ~ 0)
    • Linter
    • 静的解析 (Language Server等(オンライン型検査))
  • コンパイル
    • 型検査
  • テスト時
  • 本番実行時

最高のデバッガー: コードを書いた瞬間、現在・未来において起こりうるあらゆる種類のエラーとその原因を提示し修正案を出してくれるやつ
要素:

  • ① コードを書いた瞬間: 問題を即座に認識
  • ② 現在・未来のエラー: 潜在的に危険なコード含めて指摘
  • ③ あらゆる種類: 構文・型・アルゴリズム何から何まで
  • ④ 原因の提示: 問題がなぜ起きたかまで提示
  • ⑤ 修正案の提示: 手動バグ取りとの決別

こんな理想的なデバッガーはない.
ただし、部分的に満たす方法はある.

  • 型検査 (①④): コードを書いた瞬間(①)に、現在起きている型エラーを、検査失敗位置と共に(④)示す
  • Lint (①②④(⑤)) : コードを書いた瞬間(①)に、潜在的に危険だと知られている(②)コードパターンの位置(④)を示し、可能であれば修正案を提示する(⑤)

型検査のいい所: 検査に引っかかった場所 (the cause) を明示してくれる => tfindをすごい小さくしてくれる

難しいところ: 単体で導入されるバグは除去が比較的容易。
複合的バグが危ない(トリガーされない危険な振る舞いが起動してしまうような動きが活性化する。それってバグがinjectionされていたってことでは?)
存在するが決して起きないバグはバグか (return より後ろに埋め込まれたバグ)

Lint: 言語仕様が定めるSyntax・Semanticsは満たしているが人々が意図するSemanticsから乖離している(潜在的に危険な)コードを指摘する.

定義域と終域はtdとtfindを縮める効果がある.
td: 組み込まれたテスト(バリデーション)が常時発動するから.
tfind: “契約による設計”で探索範囲が絞れる.
よりcordlessになれば素晴らしい
-> したいことは関数の設計であって、デバッグではない

bug injectionの確率をそもそも下げる.
lint, その他ツール.
=> bug injection自体はされてる。それがリアルタイムで指摘・修正されているだけで

デバッグ比率

テストの工程比率
IPA (2016) "「ソフトウェア開発データ白書2016-2017」ご紹介" p.13 ref

stack overflow (2010) "What % of programming time do you spend debugging?" ref

1 ソフトウェア開発に置いて、デバック、テスト期間を どのく… - 人力検索はてな

早期発見の重要性を示した文献

「多段式エラープルーフ」

定義域と値域の完全なテストに成功し、かつ、完全な関数同士のみをチェーンした場合、全体での無エラー性が理論上保証される。
ちょっとトリッキーに拡張すれば、良くテストした純関数のみをチェーンさせるなら、デバッグコードはプロダクションコードから排除しうる。

デバッグで何をしているのか

なんらかの外部に見える異常が出たら

  • 異常値を取る変数を探す
  • 異常値を生む処理を探す

ソフトウェア工学の大原則: バグ検出はより早期だとうれしい