プログラミングと才能のはなし

どうも最近更新できてないので、今日はコード無し、ちょっと駄文を書かせてもらいましょう。すこし古い記事ですが・・・

プログラミングできる人とできない人との間の深い溝
http://d.hatena.ne.jp/masatoi/20090707/1246965336

昨日、たまたまTwitterで見かけて、興味を持ったブログ記事です。(このブログ自体は、こちらの記事の和訳のようですね。)

ここで、次のような問題が掲載されています。

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

上記のような問題をプログラムのコードを見たことがまったくない学生に出題した時。大きく次の3パターンに分かれるのだそうです。

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

さらに、上のブログで紹介されている論文の一部を次に掲載します。

もしこのテストが入試の基準として用いられ、一貫性のあるモデルを持つことが出来た学生のみが入学していたとすれば、プログラミングのコースをパスする学生数の統計は変わってくるだろう。全体では61人中32人(52%)がコースを落としたが、最初のテストで一貫性があったグループ内では27人中6人(22%)がコースを落としたに過ぎなかった。

つまり、上記のテストで「一貫したモデル」を見付け出す事ができた人は、比較的高い確率でプログラミングのコースをパスしているというデータがあるという事です。(ここでいう「学生」達の教育機関については特に触れられてはいませんが、その教育機関にそういったコースがあるという事は読み取れます)

この記事の解釈については、

プログラミングの適性は、別の何かで穴埋めできるか?
http://d.hatena.ne.jp/eel3/20100815/1281883066

の内容が的を得ていて面白いと感じたのですが、色々見聞きしているとどうもこの実験の意図を正しく汲み取れていない方もチラホラと見受けたので、自分の解釈も一つまとめておこうかと思ったわけです。(あるブログでは、「代入なんてバケツに例えればすぐに教えられるじゃないか!」なんて書かれていました。トホホ)



そもそも、上記の設問で重要なのは、プログラミングにおける代入演算を正しく理解できる必要は一切無いという事です。
極端な話、回答者の頭の中で一定の「ルール」が組み立てられて、全ての設問についてそのルールが適用されている・・・あるいは、適用しようとしている事が確認できれば良いわけです。

もう少し続けます、IT技術からしてみれば、この設問のプログラムを適切に整えてccでコンパイルすれば、a,b共に20になるのはあまりにも自明ですが、この実験においていえば、全ての選択肢が答えと成りうるという事です。
「x=y」という計算が、xにyの値を「移動」させて足すものだと解釈すれば、a=30,b=0となります。xの値は捨ててyの値を「移動」するものだと解釈すれば、a=20,b=0となります。

なんでも良いんです。
初等数学をある程度以上学べば、ここで「=」という演算子の意味しているものが自分の知っているそれとはまったく違うものだというのには直ぐに気づくでしょう。
この時に、「=」という演算に「新たな役割=ルール=モデル」を定義し、それに一貫性を持たす事ができる能力が問われているというわけです。



さて、このテストを受けた後、この学生達が「プログラミングのコース」でどのような指導を受けたかは定かではありませんが、代入や四則演算をやって終わりという事は無いと思います。
分岐やループにはじまり、サブルーチンで処理を階層化し、再帰を学び、あるいはオブジェクト指向等の設計手法を身につけていくにあたって、対象が抽象的であればあるほど、上の設問で問われたような「モデル」を定義する能力は問われていくのでは無いでしょうか。

所謂プログラミングの入門書では、変数を箱やバケツに例えたり、オブジェクトの説明に車の設計書と生産ラインの話しを持ち出したりするのはよくある事です。
それでもその機能の形式的な役割を説明する事はできますが、根本的な概念は具体例やそれらしい喩え話を持ち出しただけで理解できるものでは無いのです。(特にオブジェクト指向が誤解されやすい事は多くのエンジニアの方がご存知と思います。)



最近、プログラミングへ応用するために、初等数学から数学を勉強し直していたりするのですが、「抽象化」とか「モデル」というのはこの世界では当たり前の用語なんですね。
代数学を業務システムの設計に応用するなんていう考え方を2ちゃんねるHaskell板で見かけた記憶がありますし、証明駆動プログラミングなんていう開発の手法もあります。
そういえば数学の強い方はプログラミングにも強いイメージがありますね、Twitterの優れた方たちを見ているとこの辺りは確実にリンクしたスキルだなぁ、なんて思ったりするわけですが。

この二つをひも付けるものは何かと問われれば、やはり「抽象化」する能力、一貫した「モデル」を作りあげる能力だと言えましょう。
そう考えれば、上の実験やその結果はなにも不思議な事では無いように感じます。

プログラミングについては、業界内外問わず、しばしば「才能」という言葉が使われます。
そもそも、「プログラミングの才能ってなんやねん」という事については、自分も少なからず考えていて、漠然と「抽象化の能力」なんていう適当な表現を使ったりする事はあったのですが、最初に紹介した記事のおかげで少しだけ、その答えが見えたような気がします。

まぁ、理屈を並べるだけでなく、自分もちゃんと人並みにプログラミングできるようにならないといけませんが・・・
最後に、冒頭で掲載した記事から、元になった論文の引用をさらに転載して終わりにします。おやすみなさい。

十分なデータ数がないので疑わしいままではあるが、最初のテストにおける3つのグループの違いは「無意味なもの」に対する姿勢の違いのように見える。
形式論理的な証明、つまりプログラム(プログラム言語と呼ばれる形式的なシステムで表現されている、特定の計算が可能である形式論理的証明)は、それ自体はまったくの無意味(meaningless)である。あなたがプログラムを書くためには、あなたがプログラムに意味して欲しいことがなんであれ、これを受け入れる必要がある。機械は盲目的にその無意味なルールに従い、何らかの無意味な結論に至るのだ。