読者です 読者をやめる 読者になる 読者になる

「Androidは電気羊の夢を見るか」を読みたい管理者のブログ

仕事などでの色々な発見を記事にしてます。不定期更新。

なぜプログラミングが出来ない人間がいるのか~理解に対してのいささか抽象的な解釈 その2~

bignight.hatenablog.com
の続きみたいな記事
前回の復習から

認識には2段階ある

人間の認識には2段階ある。というのは前回の記事で述べた。Wikipediaには簡潔にこんなことがか書かれてた。

哲学における認識[編集]
認識は、伝統的には、大きく経験的認識と理性的認識に分けられ、さらにその論者の哲学体系により異なる部分もあるが、おおむね、直観的認識、感性的認識、理性的認識、知性的認識などがあるとされる。それぞれの認識の成立には、感性、直観、理性、そして知性ないし悟性などの主観あるいは精神の機能が働くとされる。
認識についての哲学における研究分野が認識論である。認識の起源、認識の本質、真理論などで様々な解釈がある。
心理学における認識[編集]
科学としての心理学においても、認識(Cognition)という概念・用語が使用される。心理学の場合、科学であるため、基本的に外界の素朴実在論を前提としており、このため、哲学における認識とは異なる定義や概念となる。
心理学で、またその他の関連分野で使用される「Cognition」という言葉・概念は、場合によって「認知」という訳語が相応しい場合がある。en:Cognitive science などは、認識科学ではなく、認知科学である。また、en:Cognitive psychology は心理学の分野のひとつであるが、これは認知心理学という。認識心理学とは言わない。
心理学での認識過程[編集]
心理学では、認識とは、心的な過程のひとつで、外界から得た情報が意味づけされた上で意識に上ることを言う。ここで、外界からの情報が知覚である。これは、身体からの信号である感覚をもとに構成されたものとなる。
この知覚に対して意味づけを行う過程には知性的能力(理性・悟性)や知識が介在し、同じ対象に対しても個人ごとに同じ認識をしているとは限らない。
ここで、知覚していることは必ずしも認識していることを意味しない。いわゆる、「見ている」と「見えている」の違いである。 また、認識はそれだけではブラックボックスで、行動・発話などの出力行為によってのみ客観的に確認できるものである。
認識 - Wikipedia

前回述べたことはWikipediaでいう
1段階目の認識⇒知覚
2段階目の認識⇒認識
ということになるのだろう。
復習終わり。


この記事では2段階目の認識、すなわち「物事の理解」について問題にしたい。

経験的認識と理性的認識(もしくはぼくが形式的理解と概念的理解と呼ぶもの)

哲学における認識[編集]
認識は、伝統的には、大きく経験的認識と理性的認識に分けられ、さらにその論者の哲学体系により異なる部分もあるが、おおむね、直観的認識、感性的認識、理性的認識、知性的認識などがあるとされる。それぞれの認識の成立には、感性、直観、理性、そして知性ないし悟性などの主観あるいは精神の機能が働くとされる。
(太字は筆者)
認識 - Wikipedia

用語は統一しておいた方がいいと思うのだけど、語りやすいのでオリジナルの用語を使う。
Wikipediaによる
経験的認識を形式的理解
理性的認識を概念的理解
と呼んだ所であたらからずも遠からずだろう。
これに「メンタルモデル」を付け加えたい。メンタルモデルを(経験による)時として誤った概念的理解と定義する。


人間が言葉を習得する過程について考えたい。


人間が「机」という概念(若しくは認知モデル、メンタルモデルと呼ぼう)を構築する過程は経験を外しては語れまい。
コンピュータが猫という概念を理解したと話題になったが、これも人間が言葉を覚える過程に似てることと思う。
(参考)
ディープラーニングでおそ松さんの六つ子は見分けられるのか 〜実施編〜 - bohemia日記
猫を認識できるGoogleの巨大頭脳 « WIRED.jp


あるいはウィトゲンシュタイン言語ゲームとか。

言葉とは、客観的な根拠によって成りたっておらず
「伝統的文化的に決められた生活様式というルール」
を根拠として述べているにすぎない。
言語ゲーム - 哲学的な何か、あと科学とか


自然言語なんてファジーなもので、単語一つ一つに厳密に定義を与えて使ってる人なんてまずいない。
単語の意味は経験的に決定されるし、形式的に使われる。
使われる状況と単語とがワンセットになって僕らは言葉を理解している。
それは外国語の習得についても同じだ。

英語は話せてもプログラミングは出来ない人

世の中見渡してみると英語は話せるのにプログラミングが出来ない人というのは確かにいる。
僕なんて英語は話せないのにプログラミングは出来る。不思議なものだ。

何故だろう。これから考察していきたい。

形式的理解

プログラミングでは、最初に
#include <stdio.h>はオマジナイと教わる。
この「オマジナイ」的理解の仕方も「形式的理解」と呼ぶ。


この「形式的理解」は反復練習をつむことによって身につく。
たとえば二次方程式の係数を二次方程式の解の公式に当てはめるということを何度も繰り返す。
これを形式的理解と呼ぶことにしよう。
形式的理解の上では「マイナスかけるマイナスはプラス」とアプリオリに受け入れることになる。

メンタルモデルのぶち壊し

算数の例を持ち出そう。
たとえば割り算を実行すると解は割られる数は小さくなるというメンタルモデルを構築した人間がいるとする。
そういう人間が「割り算を実行して割られる数より解が大きくなる」という自体に直面したらどうなるか*1
この場合4つのパターンが考えられる。

  1. 自分の構築したメンタルモデルに執着するか
  2. 自分の構築したメンタルモデルを捨てていったん保留にするか
  3. 自分の構築したメンタルモデルを捨てて新たなメンタルモデルを探すか
  4. そもそもメンタルモデルを構築してなかったか

「割り算を実行すると解は割られる数は小さくなる」というのは言うまでもなく間違いで、そうした認識がどうして発生したかと言えばひとえに帰納的理解、すなわち経験的認識による所が大きいのだと思う。
1.の「自分の構築したメンタルモデルに執着する」人は「割ることによって数が大きくなる」という概念がどうしても受け入れられない。
2.の「自分の構築したメンタルモデルを捨てていったん保留にする」人にとって、まぁ問題ないだろう。
3.の「自分の構築したメンタルモデルを捨てて新たなメンタルモデルを探す」人にとっては、新しいメンタルモデルを探す必要が出てきてそれが学習コストになる。
4.「そもそもメンタルモデルを構築してなかった」形式的理解をしてる人だ。

いずれにしても割り算という演算を「単位当たりの数を求める演算」と概念的に理解できるのはずっと先だ。
そこに至るまで幾多のメンタルモデルの構築と破壊を経験する必要が出てくる。そうして人は本質的な理解に近づく。

プログラミングの話をしよう。

d.hatena.ne.jp
リンク先の記事によると60%の人間はプログラミングの素質がないという。

多くのプログラミング学習者が理解に苦しむ問題を調査した所、以下のような結果が得られた。

代入とシーケンス実行
再帰と繰り返し実行
並列実行
プログラマの適性検査 - カレーなる辛口Javaな転職日記

  • 代入とシーケンス実行→文字列を書くだけでコンピュータが仕事をするというメンタルモデルがない人にとってはこれは難しいことだろう。=は同じと理解してる人にとって代入は難しいことだろう。変数に値が入るという概念もよくわからない。
  • 再帰と繰り返し実行→上のシーケンス実行をメンタルモデルとして構築した人にとって、シーケンス実行のメンタルモデルを一度壊す必要が出てくる。再帰とは関数内で同じ関数を呼ぶことでこれもやはり難しい。
  • 並列実行→スレッドのことかな。コンピュータは同時に一つの仕事しか出来ないと思ってる人にとって(以下同)

このように学習する過程で人は色んなメンタルモデルを構築しては破壊していく必要が出てくる。


ぼくが出会ってきた人の中で、英語(=多国語)が話せてもプログラミング出来ないという人間が2人ほどいた。
ぼくなどその逆でプログラミングが出来ても英語が話せない。
面白いものだな、と思う。

プログラミング事始め

プログラミングを習い始めはまずおおよそこんなコードを書くだろう。

#include <stdio.h>
int main(){
printf("hello world");
return 0;
}

#includeとかint main(){とかreturn 0;とかはオマジナイなのだよ、と教わる。
"#includeとかint main(){とかreturn 0;とかはオマジナイ"
という「メンタルモデル」が学習者に形成される。
この段階では「オマジナイ」なのだから形式的理解で充分だ。だからこの段階では反復練習が有効な方法となるだろう。
「文字列を書くだけでコンピュータは仕事してくれるんだよ」と何度も何度も自分に刷り込んでメンタルモデルを形成していく。
ぼくなんかその点、運がよくてまず最初に先生がコンパイラの役割について説明してくれた。
だから文字列を打ち込むだけでどうしてコンピュータが仕事をしてくれるのか、悩まずにすんだ。


そのうちその「メンタルモデル」に例外事項が発生する。
たとえばWindowsプログラミングだと#include <stdio.h>は書く必要がなくて、C++になると#include <iostream>になるだとか、そこらへん。
となると学習者は最初に形作られたメンタルモデルを破壊する必要が出てくる。
メンタルモデルの組み立てなおしが起こる。


ここで学習者の「頭のやわらかさ」が試されるわけだ。


C++なんか

cout <<"文字列"<<endl;

と書くわけだけど多くの人がここで挫折するという。

それは「<<」のメンタルモデルが構築できないからだろう。


この段階で、
「コンソールプログラムではstdio.hをインクルードする」と理解するものを形式的理解
「#include<stdio.h>は標準ライブラリを読み込んでる」と理解するものを概念的理解
と定義する。

ぼくは英語ができない

ぼくは英語ができない。理由は分かりきってる。面倒くさがりやで理屈屋だからだ。
英語はファジーな言語で「概念的理解」というものがほとんど通用しない。一つ概念を理解したと思ったらその例外が必ずといっていいほどある。
どうしたもんか。
だから何も考えずに反復練習するのが有効なのはわかりきった話なのだけど、ぼくはそれが出来ない。面倒くさがりやだからだ。
英語を習得するには面倒くさい過程を通ってく必要がある。

ではプログラミングはどうか。postd.cc
こんなエントリ見てしまうとそれほど出来る方ではないな、と思う。

でもプログラミングは英語に比べて「法則性」というのが明確だから「概念的理解」を容易に出来るとも言える。
たとえば「オブジェクト」の概念。


とするとぼくと間逆のタイプがいるのも想像に難くない。
すなわち「英語」的な形式的理解が要求される学問が得意な人というのがいるはずだ。
使われる場面と単語が結びつくような。
プログラミングでいえば「どんなときにstdio.hをincludeするの」ってのを曖昧に理解してるような人たち。

それは「マイナスかけるマイナスはプラス」と教わって「へーそうなんだ」と納得できる人。
そういう人は概念的理解が苦手なんだろうと想像される。


そういうぼくが「いい」と思った英語の本の書影を貼り付けとく。

英文法のトリセツ?英語負け組を救う丁寧な取扱説明書 じっくり基礎編

英文法のトリセツ?英語負け組を救う丁寧な取扱説明書 じっくり基礎編

英文法のトリセツ ~とことん攻略編

英文法のトリセツ ~とことん攻略編

英文法のトリセツ 中学レベル完結編

英文法のトリセツ 中学レベル完結編

一生モノの英文法 (講談社現代新書)

一生モノの英文法 (講談社現代新書)

英会話・ぜったい・音読 【入門編】?英語の基礎回路を作る本

英会話・ぜったい・音読 【入門編】?英語の基礎回路を作る本

ほとんど英文法の本だというのもなんともぼくらしい。

数学という言語

二次方程式の解の公式というものがある。
形式的に係数を当てはめることによって二次方程式が解けるというものだ。
数学はひどく抽象的な学問だから「二次方程式」の式の意味を理解する必要はない。要するに概念的理解は求められない。
「マイナスかけるマイナス」は形式的にプラスではあるけれど、
このことをきちんと理解したかったら「マイナス」の概念を知る必要がある。
「マイナスの概念」を理解してはじめて「虚数軸」の概念が産まれる。要するにこれは「マイナスの概念」を拡張したのであり、応用したのだ。
でも、ほとんどの人が「そんなこと知ったこっちゃない」だ。
物理学で数式を扱うとき、「形式的に式展開」できるのは「形式的理解」の範疇、
その数式が何を表してるのかを理解できるのが「概念的理解」の範疇と言うことになるだろう。


なぜプログラミングが出来ない人間がいるのか

学習においてまず最初に「形式的理解」の段階を踏む。これは「数式の展開ができる」だとか「文法に単語を当てはめることが出来る」とか、「#include<stdio.h>が書ける」とか
そういうことだ。

プログラミングをするためには自分が理解したことを応用しなくてはいけない。
英語は相手が人間だから間違った理解をしていてもある程度相手が汲み取ってくれる。
コンピュータはそういうわけにいかない。
形式的な段階でもある程度厳密性を求められる。
その上上達するにつれより概念的理解を求められるようになる。
でないと#include<stdio.h>を応用なんてできないわけだ。

このエントリで一番言いたかったことは、経験的認識(メンタルモデル)が時として誤謬を産むということだ。
一歩踏み込むためには「経験的認識」すなわち「わかったつもり」ではだめで、「概念的理解」も必要になってくるのだろう。そういう意味でコンピュータは「厳格」だ。


わかったつもり 読解力がつかない本当の原因 (光文社新書)

わかったつもり 読解力がつかない本当の原因 (光文社新書)


ここらへんの話は認知心理学をつつくと結構出てくるのだろうけど何せぼくは認知心理学は門外漢だ。なのでここら辺で筆を置くことにしよう。

追記

togetter.com
文系理系と分けて考えることがそもそも不毛でしょうね。

つまりプログラミングの素質というのは、無意味なものに対する姿勢だ。無意味なルールを受け入れて、無意味なルールで指示し、コンピュータは盲目的に従い、無意味な結論を出す。

「そういうものだ」としてルールを学ぶ。最初でつまずかなければ、githubなんかで実際に使われているコードを読む、作って試してみるしてるうちに、あっという間にスキルが伸びて世界が開ける。
なぜ60%の人はプログラミングが出来ないのか|舩木俊介 『かつて未来とよばれたソサエティ』

おおむね同意。メンタルモデルという言葉の使われ方に差異があるようだ。

メンタルモデルは、外界の現実を仮説的に説明するべく構築された内的な記号または表現であり、認識と意思決定において重要な役割を果たす。メンタルモデルが構築されると、時間とエネルギーを節約する手段として慎重に考慮された分析を置換する。
メンタルモデル - Wikipedia

*1:いうまでもなく1より小さい数で割った場合である