このサイトについて
Pythonを学ぶ最良の方法とは?
プログラミングはなぜ難しいのか

プログラミングはなぜ難しいのか

4月19日(水)に開催される勉強会にお呼ばれして,お話をすることになった。10年間多くの方に読んで頂いているPythonの入門書を書いている関係もあって,つねづね「プログラミングはなぜ難しいのか」について考えたり調べたりすることが多いのだけど,当日はそのことも含め,どうすればよりよく学習できるのか,プログラミングとは何か,ということなどにも言及したいと思っている。

プログラミングが難しいのは,一言で言うと「ロジックの塊」だから,ということなんだけど,そうすると「じゃあ論理的な思考が得意な人だけがプログラミングやればいいじゃん」みたいな話になりかねないので,もう少し砕いて考えてみたいと思う。

たとえば,この手の話題でよく引き合いに出されるFizzBuzz問題

1から100までの数をプリントするプログラムを書け。ただし3の倍数のときは数の代わりに「Fizz」と、5の倍数のときは「Buzz」とプリントし、3と5両方の倍数の場合には「FizzBuzz」とプリントすること。

これを解くプログラムを作るには,二種類のハードルがある。

ひとつは,プログラム言語で実行できることがらの要素を知る,というハードル。演算(割り算の余りを得る),条件分岐,ループ,文字列の表示。

そして二つ目は,問題の条件を満たすよう,機能を組み合わせる方法を考えるというハードル。

一つ目は,言ってみれば暗記で乗り越えられるタイプのハードルなので,それほど難しくはない。問題は二つ目で,このハードルを越えるには,問題を要素に分割して,プログラム言語で実行できる命令に置き換え,問題の要件を満たすように組み上げてゆく必要がある。ここに論理的思考が必要で,このハードルは一般ピープルには容易に超えられない。プログラミングができる人は,この種の論理的思考になれているので,この種の問題を難なく解ける。

では,論理的思考が得意な人とそうでない人を分けるのはなんなのか? そう思っていろいろ調べてみると,面白いことが分かってきた。人間は「論理そのもの」を扱うのがそもそも苦手らしいのだ。

「ウェインの選択課題」と呼ばれる問題がある。

以下のように4枚のカードがある。このカードには「片面が奇数ならばその裏はひらがな」となるように作られているという。

「3」「8」「う」「キ」

本当にそうなっているかを調べるためには,どのカードを裏返してみる必要があるか。何枚裏返してもかまわないが,必要最小限の枚数にすること

この問題,初歩的な論理的思考を要求する問題なのだが,多くの人は「3」「う」を選ぶらしい。ちなみに,この答えは間違い。おそらく,FizzBuzz問題をなんなく解けるプログラマでも,多くの人が間違えるはずだ。

正解は「3」と「キ」なのだが,どうしてそうなるか解説すると,まず,「3」を裏返す必要があることは簡単に分かる(3の裏がひらがなでなかったら,ルールに反するので)。次に「8」は偶数で,偶数の裏がどうなっているかは決められていないので,調べる必要がない。

問題は「う」で,この裏が偶数だったらルールに反する,と考えてしまう人が多いのだが,「ひらがなの裏が偶数ではいけない」つまり「ひらがなの裏は必ず奇数である」とはどこにも書いていないのだ。なので,「う」のカードは裏返す必要がない。

「キ」に関しては,もしこの裏が奇数だったらルールに反することになる。なので,このカードは必ず裏返す必要がある,ということになる。

この問題を見て分かるのは,人間は必ずしも論理に沿って考え,行動しているわけではない,ということだ。人間は,この種の思考が苦手なのである。

では,人間は論理的思考ができないのか,というとこれもまた違う。試しに次の問題を解いてみて欲しい。

ある国に入国するには,コレラの予防接種が必要となっている。あなたはその国の空港で,入国管理を行う立場にある。空港利用者はカードを持っており,カードの表には,その人が入国希望者かどうか,裏面には受けた予防接種の種類が書いてある。

「赤痢,疫痢」「コレラ,赤痢」「一時立ち寄り」「入国」

上のようなカードがあるとき,入国のルールを満たしているかどうかを確認するためには,最低限どのカードを裏返す必要があるだろうか。

この問題で,多くの人は「入国」と「赤痢,疫痢」の二つを選択するはずだ。そして,その選択は論理的に正しい。

さて,よく見ると,この二つの問題は論理的な構造がまったく同一なのだ。にもかかわらず,二番目の問題の方が正解率が高い。なぜだろうか。この問題を研究すると,どうも人間は「許可」という文脈の時には,論理的な推論をする傾向が強い,ということらしい。

このことから分かるのは,世の中には「論理が分かる人/分からない人」という区分があるわけではない,ということだ。「問題を抽象化したり,主客を変えたりして,論理的に問題をとらえられるような方法を知っている人」と「そうでない人」がいるだけなのだ。

だから,今,プログラミングが苦手な人も,「考え方」を学びさえすれば,プログラムを作れるようになるはずだ,というのが僕の持論なのだ。

さて,そもそもなんで人間が許可の文脈で論理的な思考を行うようになったのだろうか。多分それは,社会を形成して,コミュニケーションをしながら文明を発達させてきた人間にとって,有利な点が多かったからだと思われる。人間はこれまで,他人,社会とインタラクトするために,伝えたい内容をより効率的に伝えられるような(許可の文脈をはじめとした)手法をこらした「おはなし」によって,文明を発展させてきた。「おはなし」というのは,もっと言うと,時代やコミュニティ,環境に沿ったナラティブとしての「物語」のことでもある。こういう話を突き詰めてゆくと,プログラミングをする意味,みたいなことについてもおぼろげながら見えてくる。

勉強会では,そのようなことも含めてお話したいと思っている。残席があまりなく恐縮だが,興味のある方は是非ご参加頂きたい。

それとこれは是非言っておきたいのですが,予約語や機能がシンプルで「第一のハードル」超えやすくて,プログラムの書き方みんな一緒になるように推奨してロジックすっきりなPythonはとっても使いやすいプログラミング言語ってことです。

追記 : 勉強会は盛況のうちに終わりました。当日使ったスライドはこちらになります。

2017-04-14 12:00