序幕

あなたと私は会社の同僚です。
仕事帰りに、二人でスーパーへ寄ることにしました。
(残念なことにテレワークできない職場なんです)

焼肉弁当の巻

スーパーへ向かって歩きながら、 私は
「焼肉弁当が5割引なら、買うよ」
と言います。

いざ、スーパーへ到着してみると、
ちょっと時間が早すぎて、
焼肉弁当は、まだ2割引でした。

ここで、もし私が、その弁当を買ったら、
あなたは、どう思いますか?

気が変わったの? と思うでしょう。
言うこととやることが違うじゃん、と思うかもしれません。

しかしプログラミングの世界では、
私の行動は全く問題ありません。

「Aなら、Bである」という発言には、
Aじゃなかったときのことは一切含まれないのです。

私は
「5割引じゃなかったら、買わない」
とは言ってません。

あなたには、if文のthen側だけを見せて、
else側は見せてなかったのです。

if ( discountRate == 50 ) {
  buy('yakiniku');
} else {
  buy('yakiniku');
}

のり弁当の巻

別のパターンです。時間を巻き戻しましょう。

スーパーへ向かって歩きながら、 私は
「のり弁当が5割引なら、買うよ」
と言います。

その5分後、スーパーへ到着したところで、私が
「のり弁当が5割引なら、買わない」
と言ったら、あなたは、どう思いますか?

おいおい、矛盾してるじゃん、と思うでしょうか?

いいえ、矛盾しません。
どちらの言明にも反しない結末が存在するからです。

たとえば、この日、のり弁当は大量に余ってて(ありえないけど!)
7割引になっていたのです。

それを買おうと買うまいと(何なら2つ買っても)、
先の私の2つの発言には反しません。

もし実際に5割引だったら、私も言い訳できなかったでしょうが…。

if ( discountRate == 50 ) {
  // ここに来たらバグ!
} else {
  buy('nori');
}

いくつかの言明(真実・前提)から、新しい別の言明を導き出すことを
「推論」とか「演繹」と呼びます。いわゆる三段論法とかのことです。

人間は、いつか死ぬ。ソクラテスは人間だ。
よって、ソクラテスは、いつか死ぬ。
みたいな。

プログラミングも、推論の繰り返しです。
ロジックを正しく(過不足なく)表現し、複数のロジックから
別のロジックを正しく導き出すことが大事です。

推論が間違っていると、ifに入らなかったり、
思わぬelseに分岐してしまったり、無限ループになったりします。

では、どうすれば演繹力を磨けるのか?
残念ながら銀の弾丸は無さそうです。
訓練するしかないと思います。

間違った推論を指摘してくれるメンターがそばにいればいいですね。