プログラミングできる人とできない人との間の深い溝

どうしてプログラマに・・・プログラムが書けないのか?を読んでいて出てきたので出展の一つを訳してみた。Separating Programming Sheep from Non-Programming Goatsの和訳。

プログラミングというものには向き不向きが強く出るということはわりと知られていると思うが、このエントリではプログラミングができるかできないかは比較的簡単なテストによって、プログラミングの訓練を始める前の段階で分かると主張している。どうしてプログラマに・・・プログラムが書けないのか?では、そもそもこの事前テストをパスしていないような人達までプログラマとして応募してくると言っており、その判定法として有名なFizzBuzz問題を挙げている。


訳出はじめ


実に多くの人がリンクしているこの論文(PDF)では、プログラムやプログラミング言語に触ったことがない学生達を対象に、「プログラミングのできる羊とできない山羊を区別する方法」を提案している。

おしなべてプログラミングの教師はプログラミングができる学生とできない学生の二つの山ができることに気付いている。それぞれの山は独立な正規分布を成している。プログラミング教育に関する研究のほとんどすべてが教授法についてのものである。すなわち、言語を変え、応用分野を変え、IDEの利用法や仕事へのモチベーションの維持について教えるわけだ。しかしそれらの試みはなかなか上手くいかず、二つの山は依然として残り続けている。
我々はコースの開講以前に、プログラミングができる方の学生達をピックアップする実験を行った。そして実際に二つの山の一方を選ぶことができた。これは信じがたいことかもしれないが、以下の話を聞けば納得できるだろう。我々はこの方法がなぜ上手くいくのかについて正確なところを知っているわけではないが、いくらかの良い意見を持っている。

私はプログラマーと非プログラマーの区別がこんなにも早い段階ではっきりとつくということに気付いていなかった。Dan Bricklinはその感動を彼のエッセイ”Why Johnny Can't Program”の中で述べている。しかしこの現象は計算機科学を教えている人々の間では明らかに一般常識であった。

電子計算機が1950年代に発明されて以来、多くの変化が起こったが、頑として変わらないこともある。とりわけ次のことが言えるだろう。「かなり多くの人々がプログラミングを学ぶことができない」。すなわち、毎年計算機科学の学部1年生の30%から60%は最初のプログラミングのコースを落とすということだ。
経験豊富な教師にはこの事実が身に染みており、彼らはうんざりしている。
その一方で、目を輝かせている初心者の方では、この老人は何か間違った方法で人を教えてきたに違いないと信じており、自らの苦い経験を通してそれが真実であると知ることになる。このようにして1960年代から始まったこの問題は二世代に渡って残り続けている。

読者はプログラミング適性を判定する彼らの実験は複雑なものではないかと思うかもしれないが、それは違う。
第一の問いはこのようなものだ。

int a = 10;
int b = 20;
a = b;

aとbの新しい値は以下の組合せのうちどれか:

  • a = 20 , b = 0
  • a = 20 , b = 20
  • a = 0 , b = 10
  • a = 10 , b = 10
  • a = 30 , b = 20
  • a = 30 , b = 0
  • a = 10 , b = 30
  • a = 0 , b = 30
  • a = 10 , b = 20
  • a = 20 , b = 10

このテストは職業プログラマにとっては自明なものだが、あくまでコードを一度も見たことのない学生にむけてのテストだということを思い起こして欲しい。他にも12問の同じような課題が出される。

この論文の著者は計算機科学における最初のハードルは以下のようなものになると仮定している。

  1. 代入と系列
  2. 再帰 / 繰り返し
  3. 同時並列性

上から順にハードルは高くなっていく。従ってテストは新米プログラマに対する最初のハードルである代入から始めていく。このテストの結果は3つのグループに綺麗に分かれる。

  • 学生の44%は代入がどのように働くかについて一貫したモデルを持つに至る(たとえ正しくなくとも)
  • 39%の学生は代入のモデルとして一貫したものを形成できない。
  • 8%の学生はふてくされて回答を空白のままにする。

このテストは2回実施された。最初の一回目を何の説明もなしに行い、3週間後にもう一度行った。印象的なことは、一回目と二回目では実質的にグループの変化がほとんど無かったことである。つまり、一回目のテストであなたが心の中に一貫したモデルを得られるかどうかが最初のハードルになっている。

著者はプログラミングができることと一貫したモデルを心に持てるかどうかの間には極めて高い相関があることに気付いた。

明らかに、Dehnahdiのテストはプログラミングのできる羊とできない山羊を分離する方法として完全ではない。
にも関わらず、もしこのテストが入試の基準として用いられ、一貫性のあるモデルを持つことが出来た学生のみが入学していたとすれば、プログラミングのコースをパスする学生数の統計は変わってくるだろう。全体では61人中32人(52%)がコースを落としたが、最初のテストで一貫性があったグループ内では27人中6人(22%)がコースを落としたに過ぎなかった。我々はこのコースの可否についての事前知識を与える予測テストを行ったといえる。しかもその正確性はかなり高い。これは我々の知る限りでは予測に成功した最初の実験である。

この論文の原稿は、味気ない学術論文かと思いきや、実に楽しめるものだったので、皆さんにも通読されることを強くお勧めする。実際のところ、ブログのエントリのように読みやすかったのだ。これは例えば以下のような興味深い洞察で満たされている。

十分なデータ数がないので疑わしいままではあるが、最初のテストにおける3つのグループの違いは「無意味なもの」に対する姿勢の違いのように見える。

形式論理的な証明、つまりプログラム(プログラム言語と呼ばれる形式的なシステムで表現されている、特定の計算が可能である形式論理的証明)は、それ自体はまったくの無意味(meaningless)である。あなたがプログラムを書くためには、あなたがプログラムに意味して欲しいことがなんであれ、これを受け入れる必要がある。機械は盲目的にその無意味なルールに従い、何らかの無意味な結論に至るのだ。
この実験で一貫性を持つことができたグループはこの事実を事前に受け入れていたことを示した。すなわち、彼らは数学的計算の問題をルールの集まりという観点から見ることができ、それらが最終的にどこを目指しているにせよ、それを無視してルールに従うことができるということである。一方で一貫性を持てなかったグループはそこには無い意味を探した。空白で出したグループはそれが無意味であるとみて、それを扱うことを拒否した。

コンピュータの使い方は誰もが知るべきだが、誰もがプログラマになる必要はない。
しかし実際のプログラミングはどうやら計算機科学の新入生のかなりの部分集合に文字通り「教えられないもの」であるということは少し気掛りである。明らかに誰もが我々のように無意味なルールと無意味な結論に魅了されるわけではないのであるが、私には何故そのような違いが現われるのか想像できない。


訳出おわり

  • 結局、プログラミングや数学に求められるのは抽象的なものを抽象的なままで扱う能力ということになるのだろう。抽象的な概念やルールに必要以上に意味を求めたり、具体的な身の回りのパターンに無理矢理当てはめようとするとモデルとしての一貫性が崩れ、抽象化した意味がなくなってしまう。
  • 中学校で最初にやる代数では、多項式の展開はこう、因数分解はこう、といったように機械的に式変形していくと方程式の根が求まるプロセスを踏むわけだが、式を展開したりまとめたりしたところで意味は同じである。それ自体に意味があるわけではないということで、あれもある種の無意味なルールに従う訓練だったのかもしれない。
  • ブコメで代入の問題の正解を気にしている人がいたのですが、上の問題に正解というものは無いです。このようなコードを見せられたときに、全く前提知識の無い人がどういうモデルを構築するかはその人の勝手だからです。重要なのは自分で適当に設定したモデルに従い続けることができるかどうかだというお話でした。
  • 個人的にはここで言われているようなことは先天的な能力というよりは単なる思考習慣の一つに過ぎないと思っているので、訓練あるいはふとした気付きによっていくらでも乗り越えられる溝だと思っている。