最小限の再現
プログラムを書いていてよくわからないことがあった時に「最小限の再現コードを作ろう」というアプローチを取ることがある。
これは明示的に習った記憶がなく、多分先輩プログラマのデバッグを傍で見てるうちに自然に獲得したのだろう。
これがどういう行為なのか言語化すると問題解決の方法の理解に良さそう。
その「よくわからない」は具体的にはどういう状態か?
書いたプログラムが期待通りに動かない
期待通りに動かないプログラムのどこを修正すれば良いかがわからない
二分探索デバッグができない。デバッグ実行もできない。
順次実行されるプログラムが期待通りでない挙動をした場合は、途中でブレークポイントを置いて「このタイミングでは期待通りの状態か?」を確認することで、問題の場所をそれ以前なのかそれ以降なのか絞り込むことができる。これができない状況。
なぜできないのか。
それは「分割できない処理」だと認識してるからだな。
自分の書いたプログラムの場合は分割できるが「信用している外部のコードにXを入れたら、Yが出てくると思ったのにZが出てきた」という状態だからだ。
「一塊りの処理であって、分割できない」と思い込んでるからだ。
この時に「フレームワークのコードを読む」というアプローチもある。
認知的な負担を減らすために、無意識に抽象化して「一塊りの処理だ」と思い込んでいるのだな
で、読むアプローチもある一方で、しばしば「膨大で、どこを読んだら良いかわからない」になる
今回は具体的にはTypeScriptの型の仕組みによくわからないところがあるのだが、ここでTypeScriptの関連コードを読むことが「大変」だと無意識に思って避けているわけだ
「信用している外部のコードにXを入れたら、Yが出てくると思ったのにZが出てきた」という状態で、つまり僕はその外部のコードの挙動を正しく理解できていない。その外部のコードが、実際にはどんな要素の組み合わせでできているのか把握してないので「大きな一塊のタスク」に見えていて、その大きさが見積もらないことによってやる気が出ない。
というような議論は今までにもしてきたけど、最小限の再現コードを作る話はそれとは少し切り口が違う
「外部の一塊りの処理」を複数の小さい処理に分割していくのと違って、一塊の処理はそのままで「その処理に渡す入力データ」を小さくしていく作業
再現性がない時に再現性を求める話とくっついてるけど、今回の場合「再現性はある」「最小限にしたい」だな
再現性があることが前提で「ここは問題の再現に必要ではないので削ろう」を繰り返していく
「ここは問題の再現に必要ではないので削ろう(実験)→問題は再現し続けるか?(観察)」
仮設検証プロセスとか世の中では言うけど、プロセス全体に明確な仮説など立ててなくて「ここは不要では」という小さい仮説があるだけ、プロセス全体は「最小限の再現コードを作ることが問題の解決に有用である」という仮説の検証
仮設検証プロセスにおいて仮説を「ゼロから作らなければいけない」という思い込みは適当でなくて、しばしば定型的パターンがある
最小限の再現コードを作るプロセスが小さい仮説検証の集まりなので「よくわからない」ものに対して「必要ないはずだ→削る→再現する」なら問題のサイズが小さくなるし、「→再現しない」なら自分の脳内の理解と現実の現象の間のギャップがわかる。どちらにせよ問題解決に対して前進する。
「よくわからない」で手が止まるのは有益ではないので、こういうアプローチによって問題解決を進める
このアプローチは、再現性があって、何度も繰り返し実験ができる場合にのみ使える。例えば対人コミュニケーションで、こちらの入力に対して相手が予期しない問題のある挙動をした場合に、繰り返し問題の起こる入力をすることは適切な問題解決ではない
文脈
https://www.facebook.com/1129148772/posts/10220683212006738?d=n&sfns=mo
現時点でのメモ
問題を最小限にしようとして一部の実装をanyで置き換えたが、それ自身が問題を発生させる
単体では問題なく動いてたREVERSEの有無が結果に影響することがわかった
つまり「ここは検証済みで問題はない」と思ってたところに問題がある
要素単体では問題ないが、組み合わせによって問題が起きる
たぶん問題の発生するタイミングが違う。型のインスタンスを作成するタイミングで、与えられた型引数がリテラル型なら無限ループに陥らずに処理できるが、一般の型の場合は「それがいつかは終了すると型である」とわからない
エンジニア・光成 滋生の「バグを突き止める技術」 | サイボウズ式