2017年8月28日月曜日

数とは何か

ここ数年、ずっと考えていること

僕は工学部化学系の出身で、数学どころか物理も結構ええかげんな感じでしか勉強したことがない。でも、今の僕の専門は、物理で、しかも応用数学チックなところにある。だから、物理や数学のことをずっと独りで勉強してきた。
いろんなことが少しずつ解けてきて、僕自身は満足なんだけど、後から考えると、僕が試行錯誤して学んできたことの多くは、教えてもらえれば苦労なんかしなくてよかったな、って思う。その最たるものが数学だ。

大学の数学で強烈に覚えているのは、僕たちを全く寄せ付けない、εーδ論法だ。一体全体、なんでこんな回りくどいことをしなければならないんだろう?これが理解できない僕たちは、数学に触れてはいけないんだろう。数学は才能の学問であり、才のない僕らは教育すら受ける必要がない、そういう分野なんだと聞かされてきた。理論物理の世界では、SU(2)とか、わけのわからない群論記号で議論が行われる。だからその分野も僕の踏み入れてはいけない領域なんだと思ってた。
でも違った。ある本を読んで、εーδ論法がなぜ必要なのか、理解できた。群論のことも、理解できた。そのおかげで、いろんな数学が一気に理解できて、SU(2)とかも、おおむねわかった。僕に必要だったのは、ちゃんとした説明だけだった。

苦労して勉強してきたおかげで、僕はその先に進むことができるような気がしている。今興味があるのは、「数」のこと。結局は群論なんだけど、様々な物理の世界を特殊な「数」に割り当てることを目論んでいる。例えば、テンソル。異方性を持つ物性値はことごとくテンソルになるけど、このテンソルはある種の複素数の性質を持っている。量子力学では複素数のベクトルとか行列とかが活躍するんだけど、複素数のベクトルや行列って特殊な「数」としての性質を持っている。そういう広義の「数」の概念で、僕のかかわる物理の世界を書き直してみようと、最近画策している。

数の概念の拡張

小学校以来、僕たちは算数・数学で「数」の概念を拡張し続けてきた。最初に習ったのは「正の整数」あるいは「自然数」だ。0を含むかどうかは微妙だけどね。その次に習ったのは「小数」だったと思う。次に「分数」。中学校になって「負の数」「無理数」。高校になって「複素数」を順に習った。その時の僕は気づかなかったけど、「ベクトル」と「行列」もある意味「数」だった。高校の先生はそんなことを全く教えてくれなかったけどね。
こういう順に並べると気づくと思うけど、僕たちは順番に「数」の概念を拡張してきたことになる。例えば、「小数」は「自然数」を含み、「分数」は「小数」を含む。それぞれのカテゴリーで、計算の様子が少しずつ変化し、それぞれに特徴があるものだ。例えば、「分数」では除算が、分子分母を入れ替えて積を取る、という演算になって、積の一種として扱えるようになる。

ここで、εーδ論法の話が絡んでくる。εーδ論法は、「小数」を含む「数」に対して利用できるツールである、ということだ。「小数」を含む「分数」や「無理数」でも自動的に利用できる。これは、εーδ論法を用いて証明された定理は、利用範囲が広いこと意味する。
εーδ論法で必要とされるのは、対象がコンパクトである、ということだけだ。コンパクトという概念は、二つの「数」の間をどれだけ小さくとっても、まだまだ間の「数」を見つけてこれるような、そういう性質のことだ。「数」と「数」の間にちょっとぐらいの穴があっても構わない。ただ、隙間が見つけられれば良い。その典型例が「小数」だ。「小数」では、一部の「分数」や「無理数」が表現できない。つまり「穴」がある。でも、桁を下げてゆけば、いくらでも隙間を見つけることができる。そういう例は結構多い、と数学者たちは考えている。そういう「世界」で利用できる強力なツールがεーδ論法ということだ。ちなみに、「微分」という概念は「穴」があると都合が悪い。だから、微分ではなくてεーδ論法を使うのだ。
概念だけで説明されると、とても手に負えない「コンパクト」という概念だけど、「有理数」「無理数」で説明したら、そんなに難しいものでもない。

注釈:隙間が無限に見つられるという定義は、厳密には「稠密」で、コンパクトというのはそれが局所的に収束すること、あるいは収束する状態のこと。

特殊な「数」

僕たちの「数」の概念の拡張は基本的に高校数学で終わっている。でも、仕組みが分かったのだから、もっと先に進んでもよい。

僕が特殊な「数」に興味を持ったきっかけは、「複素数の行列表現」だ。虚数単位$i$は$\sqrt{-1}$として定義され、それ以外の定義は教えてもらえない。ところが、ハミルトンの四元数を勉強した時、3種類の虚数単位が紹介され、それぞれの行列形式が提示された。僕はとてもびっくりした。厄介な虚数単位が3つもあるんだから!そして、それぞれの虚数単位に別々の行列が対応するというのだ。わけがわからない。
もっとびっくりなのは、三元数とか五元数とかはなくて、普通の複素数である二元数の次は、四元数でその次は八元数だそうだ。ハミルトニアンに名を残す天才ハミルトンが三元数を探し続けて行き詰まり、ある日突然、橋の上を歩いていた時に四元数を思いついたそうだ。あまりの嬉しさに、橋にその発見を落書きしたと伝えられている。

さて、四元数にはいろんなバリエーションがあるとされている。split-quarternionと呼ばれる「数」では、二乗したらー1になる2つの虚数単位と、二乗したら1になる3つめの虚数単位を用いる。二乗したら1になる虚数単位って意味が分からないぐらいだけど、そういう性質を持つ行列が定義出来て、split-quarternionを具体的な「数」として計算することが可能になっている。そして、split-quarternionで用いられる、二乗したら1になる虚数単位を使った二元数というのも考えることができる。こうしてできる新しい複素数はsplit-complex number と呼ばれる。split-complex numberは、自動的に対称行列に対応する。逆に対称行列はすべてsplit-complex numberであると言える。物理の世界では、異方性をもつ物理量のほとんどは対称行列で表現できる。つまり、そのような物理量はsplit-complex numberということだ。split-complex numberには特有の性質がある。その「数」としての性質は、異方性をもつ物理量の現実の性質と深く結びつくはずだ。僕はそこに興味がある。

量子力学の一つの謎を考察する

量子力学ではDaggerという演算がしばしば用いられる。行列に対し、転置と複素共役を同時行う操作と定義されている。量子力学では、しばしば転置と複素共役がセットで表われ、それぞれを単独で用いることが少ない。なぜなんだろう?

そのヒントになるのが、虚数単位の行列表記だ。通常の虚数単位は$i$だけど、$\begin{pmatrix} 0  & 1 \\ -1 & 0 \end{pmatrix}  $のような行列を用いてもよいらしい。$\begin{pmatrix} 0  & 1 \\ -1 & 0 \end{pmatrix} ^2= \begin{pmatrix} -1  & 0 \\ 0 & -1 \end{pmatrix}  $ なので、確かに$i$の性質を持っている。このように表記は違うけど、本質的に同じものを「同値」という。虚数単位の行列表現はその典型例だ。
これを用いて、$a+b i$を行列表示すると、$\begin{pmatrix} a & b \\ -b & a\end{pmatrix}$となる。一方、共役は$a- b i$なので、$\begin{pmatrix} a & -b \\ b & a\end{pmatrix}$である。行列の方を見比べると、ちょうど転置になっていることがわかる。これをまとめると、行列表示では転置すると自動的に共役になるということだ。

Daggerは転置して共役なので、2回ひっくり返って元に戻る、ということになる。じゃ、Daggerにする意味ないよね、と短絡してはいけない。複素数1個だったらそうだけど、複素数を要素とする行列(複素行列)では、そうならない。$\begin{pmatrix} a+b i \\ c +d i \end{pmatrix}$だったらどうだろう。これを無理やり行列表示すると$\begin{pmatrix} a & b \\ -b & a \\ c  & d \\-d & c \end{pmatrix}$になるだろう。これを転置すると、$\begin{pmatrix} a & -b & c & -d \\ b & a & d & c\end{pmatrix} =\begin{pmatrix} a-bi & c-di\end{pmatrix}$になる。これはDaggerの操作だ。
つまり、Daggerの本質は転置で、複素数の転置とは、複素数の共役ということだ。通常の複素行列では、要素の複素数自身に転置操作が及ばないので、Daggerによって要素にも転置操作が及ぶようにする、ということだ。

うまくいきそうだけど、この議論ではちょっとした危険をはらんでいる。先の議論では、行列の要素にさらに行列を埋め込んで、中の方の括弧を無視するということを行った。つまり、
$\begin{pmatrix} a+b i \\ c +d i \end{pmatrix} = \begin{pmatrix} \begin{pmatrix} a & b \\ -b & a \end{pmatrix} \\ \begin{pmatrix} c  & d \\ -d & c \end{pmatrix} \end{pmatrix} = \begin{pmatrix} a & b \\ -b & a \\ c  & d \\-d & c \end{pmatrix}$

こんなことが許されるのだろうか?
こんなことを許して、どこかに不都合が生じたりしないだろうか?

すこし四元数のことを調べてみる

さて、$\begin{pmatrix} 0  & 1 \\ -1 & 0 \end{pmatrix}  $以外に$i$の性質を満たす行列はないだろうか?先の四元数では、$\begin{pmatrix} 0  & 1 \\ -1 & 0 \end{pmatrix}  $のほかに、$\begin{pmatrix} i  & 0 \\ 0 & i \end{pmatrix}  $と$\begin{pmatrix} i  & 0\\ 0 & -i \end{pmatrix}  $が用いられる。いずれも$i$として使うことができるが、要素に$i$が含まれているので、あんまりありがたくない。
でもWikipediaをみると、四元数の行列表示として4x4の行列が示してある。例えば、
$\begin{pmatrix} 0 & 1 & 0 & 0 \\ -1 & 0 & 0 & 0 \\ 0 & 0 & 0 & 1 \\ 0 & 0 & -1 & 0 \end{pmatrix}$が挙げられている。これは、$\begin{pmatrix} i & 0 \\ 0 & i \end{pmatrix}$であり、先に示した四元数の虚数単位の一つに一致する。

だから、行列の要素に行列を埋め込む、というのは「OK」らしい。実はそういうのはブロック行列と呼ぶらしい。$\begin{pmatrix} A & B \\ C & D \end{pmatrix}$の各要素が行列であるようなものだ。この場合、行列式は、$ det A  det \left(D - C A^{-1} B \right) $であらわされる。僕らが良く知る行列式の公式$AD-BC$に極めて似ているけれど、行列の場合は計算順序を入れ替えられないので、$C A^{-1} B$はこれ以上簡単にはできないように思える。ただし、$ABCD$が特別な場合はそれが可能だ。特別な場合というのは、例えば、$\begin{pmatrix} a & b \\ -b & a\end{pmatrix}$だ。

この事情は複素数が行列表示できるという話のときに気づくべきことだった。つまり、複素数の積は交換可能なのに、積が交換可能でない行列で表示できるわけがないだろう、ということだ。
実のところは、積が交換可能(可換)な行列のタイプというのがあって、それらは共通の特徴を持つ。可換な行列の一つが、$a+bi$ということだ。一般に、$ a E + b X$という行列であれば、積が可換になる。さらに、$X^2 = \alpha E$を満たすとき、「普通の積」の性質を持つようになる。そういう場合、「複素数」タイプと呼ぶことにしよう。

$ABCD$が複素数タイプの場合は、$ \det A  \det \left(D - C A^{-1} B \right) =\det A \det \left(D-A^{-1}BC\right) = \det (AD - BC)$となり、僕らの知っている普通の複素行列と矛盾しない結果になる。
この事情は逆行列の場合も同じだ。だから、可換なサブ行列からなるブロック行列は、サブ行列を要素とする普通の行列とみなしてよい、となる。ということで、Daggerという操作は複素数まできっちり拡張された正当なる置換操作であるということになる。

知らない間に通り過ぎることの善悪

高校までの数学では、複素数が導入されて、つぎは行列が導入された。上記の議論に基づくと、順当な「数」の概念の拡張だとわかる。でも、僕らはそんなことは一切知らされず、計算技術の側を用いて、計算を進めてゆくうちに、なんとなく理解が進むという側面がある。だから、まずは計算ができること、を学習目標に設定するのは悪くはない。ただ、「それが全て」みたいな指導が横行していて、数学のありがたさが今一つ見えてこない。そのせいで、最近は、高校で行列を教えることをやめてしまった。

さらに、大学で学ぶべき高等数学の邪魔をしているという明らかなデメリットがある。僕たちは、「数」というものを「すでに存在しているもの」「計算の対象」とみなす傾向がある。我々が知る多くの「数」は、「たまたま現実世界の何かとうまく対応する概念」でしかない。うまく対応するのは、ある種の必然ではあるのだが、全ての「数」が何かと対応するとは限らない。多くの「数」が数字の概念からの拡張であるのは、算法を定義しやすくて調べやすいからという都合によるものだ。「数」の概念は、数字よりもずっと広い概念で、その本質は、数学者でない我々には想像の及ばない世界だ。だからと言って、数学者でない人に理解できないわけではない。

僕はプラスチックの研究者で、樹脂にいろんな微粒子や繊維を混ぜた複合材料の研究をしばしば行っている。その時、材料を「数」とみなすこともできる。混ぜるという行為は、材料同士の「演算」だ。物性測定は、ある種の「演算」あるいは、「関数」に割り当てることができる。材料同士の混合や物性測定に対応する「演算」は自明ではないが、その演算ルールが明らかになれば、材料研究が進む。だから、僕たちは、演算ルールを明らかにするという研究を行う。

このような材料研究を数学の言葉で抽象化すると、材料研究の難しい部分がどこにあるのか俯瞰できる。材料$A$と材料$B$があって、それらを混合する演算を$+$としよう。ある物性を測定するということを$f(A)$のように関数で表すことにする。このとき、AとBの混合物の物性は、$f(A+B)$になるだろう。$f(A+B)=f(A)+f(B)$のような演算則が成立するなら、材料研究はとても簡単だ。このような演算則は「線形結合」と呼ばれる。現実の演算則はもっと複雑だが、もし演算則が完全に理解できれば、僕たちは材料設計を自由自在に行うことができるだろう。だから、僕たちは、$f(X)$がどのように書き下されるのか、$f(A+B)$を$f(A)$と$f(B)$の関数として書き下す方法などを研究する。

このような抽象化は単純すぎるが、世界を数学で記述するという概念の例として、わかりやすい。僕は物理をベースにした科学者だけど、「数」について、いろいろ考えている。その時、つくづく感じるのは、「ちゃんと教えてほしかった」ということだ。


2017年8月7日月曜日

子供とプログラミング

プログラミング必修化

小学校でのプログラミング教育が必修化されます。各所で対応に向けた議論が活発化しています。
プログラミングを学ぶことはよいかどうかは、微妙です。特に、子供にプログラミングを教えるのは問題が多いと思います。それは僕自身の経験です。

中2でプログラミング

僕は中2の夏前からプログラミングを始めました。父親が、何を思ったのか、当時マイコンと呼ばれていたPCもどきを買ってきたのです。今とは違って、プログラミングしないと何もできません。だから、僕もプログラミングを始めたということです。
プログラミング言語はBASICでした。BASICでは、PRINTとかFORとかNEXTとか英単語が多数使われます。中2の英語力では、それらは単なる記号でした。僕はそれらが英単語だと思ってませんでした。つまり、プログラミングの前に言語そのものの知識が不足していたのです。
それは、小学生だったらもっと顕著になります。英単語を使うようなプログラミング言語は小学生には向きません。

Scratch

英単語を用いないプログラミング言語ということで整備されているのがScratchという言語です。英単語の代わりに、図案化されたブロックを並べてプログラムを構成します。うまくいくように思いますが、いろいろ問題があります。
日本語化されていますが、微妙に漢字が使われる点が問題です。以下は、Scratchの例です。

問題は、「押」という漢字です。小学生で習う漢字に「押」はありません。そのように、所々に習っていない漢字がちりばめられています。これを修正するのはなかなか大変です。
見てわかりますが、Scratchは、プログラミングにおける制御語を図案に変更しただけのものです。これがどれほど子供向けなのかわかりません。それから、いろいろな動作をメニューから選択するようになっていますが、それはわかりやすいとは言えません。ビジュアルの操作が多くありますが、そのせいで、メニューが複雑になっています。言語環境としてはかなり複雑です。

若い人はプログラミングをしない

プログラミング教育を強化しようという背景には、プログラマが不足しているという現実があります。特に若い人がプログラマを目指さないのです。
従来、プログラマというのは薄給のきつい職業でした。でも今は、それほどではありません。にもかかわらず、人材が不足気味です。というのも、高校卒業時点でプログラミングしたことのある人がほとんどいないからです。だから、プログラミング教育を推進しようとなっています。その根拠は、プログラミングに触れる機会が学校教育にないからだ、というものです。
しかしながら、高校のカリキュラムには、情報という科目があり、平成24年までは、情報Bという科目でアルゴリズムまで踏み込んで教えていました。しかしながら、内容がそこそこ難しく、PCを用いた実習が必須であることから、ほとんどの学校で履修していませんでした。脱ゆとりの改定で、情報は2科目になり、情報B相当科目がなくなりました。その背景には、情報Bを入試で採用する大学がほとんどないことがありました。

そもそもなぜプログラミング教育が敬遠されたのでしょう?それは、学校で教わるプログラムと巷にあふれるソフトウェアの間に、大きなギャップがあるからです。学校でのプログラミングをいくら続けても、世の中で役立つソフトウェアに到達しそうにないのです。実際、一流のソフトウェアを書こうとおもったら、かなり多くの訓練が必要です。それは学校教育では無理なのです。
それこそ若い人がプログラミングを敬遠する理由でもあります。今は、ソフトウェアの開発環境はほとんど無料で手に入りますし、情報もあふれています。僕の若いころに比べると、プログラミングを始めやすい環境です。でも、プログラミングを学ぼうとすると、情報が膨大すぎて、初心者は戸惑います。また、自分でプログラミングしなくても、ほとんどのソフトウェアを探し出すことができます。そんな中で、苦労してプログラミングして、今いちパッとしないソフトウェアを作ったとして、どれほどの価値があろうか、ということです。そういう、コストパフォーマンスの悪いことはやらない、というのは正しい判断だと思います。

それでも、誰かがソフトウェアを作らないといけなくて、人材育成が必要です。プログラミングには明らかに適性があります。適性のない人はいくら努力してもかわいそうなだけです。だから、適性のある人を見つけて、その人にプログラミングしてもらうことになります。そのためには、まずすべての人について適性があるかどうかをテストするというのがソリューションになります。高校では受験が近すぎて、受験に関係のないプログラミングを試してもらえませんでした。だから、受験とは関係のない小学生にやらせよう、という計画なのかもしれません。

プログラミングの良いところ

プログラミングができるとどんな良いことがあるでしょう?

数学は得意かもしれません。多くの数学者は良いプログラマでもあります。通じるものがあることはわかっています。しかしながら、具体的にプログラミングの何と数学の何が共通しているのかは明らかではありません。僕が感じるのは、プログラミングでは極めて複雑な論理を扱うということです。高校数学の難問の10倍くらい複雑というのはざらです。だから、そういう難しい数学の問題が楽勝になります。でも、そういう問題って数が少ないので、得点力にはつながらないんですよね。

細かいところまで理解しておかないとプログラミングできません。なので、優秀なプログラマは物事を精密に深く理解する傾向があります。多くのことを素早く理解するという受験勉強にはやや不利ですが、一度理解できれば、応用力に優れます。

物事を順序だてて、網羅的に調べることができるというのも、プログラマの特徴です。プログラミングが得意な人は、PCのトラブルに強いという傾向があります。これは、様々な選択肢を順序だてて網羅的に検証するという能力と関係があります。おそらく、プログラミング教育で最も期待されている効果だと思います。

プログラミングでは、集中力や忍耐が必要とされます。そういうのは勉学にも有利な性質です。加えて、自分の力で問題解決するという性向も重要です。これも、勉学に有利に働きます。だから、プログラミング適性の高い子供は勉強も得意で、知能が高いとみなされるはずです。プログラミングはそのような子供をピックアップするうまい方法だと思いますが、逆は不明です。すなわち、勉強のできる子はプログラミングもできる可能性が高いけれど、プログラミングを頑張ると、勉強ができたり、知能が高くなったりする効果が期待できるとは限らない、ということです。

プログラミング教育によってプログラマは育つか?

おそらく、多くの専門家は懐疑的だと思います。プログラミング教育によって、プログラミング適性のある子どもを選抜することができるでしょう。ただ、そういう子供がプログラマになるかどうかは別の問題です。プログラミングの適性は、数学の能力と相関します。数学の能力が高いと、化学や物理にも強くなります。必然的に理系科目の得点力が高く、大学受験で有利になります。大学受験で有利ということは、別にプログラマを目指す必要が無いのです。僕の場合はそうでした。

今、プログラマは復権の兆しがあるものの、あまり良い地位とはみなされていません。プログラマの多くは高卒で専門学校に通い、就職します。通常の高卒よりは収入が高くなりますが、時給換算すると効率が良くないと考えられています。というのも、プログラミングが好きというのと、プログラミング適性があるというのは、別物だからです。この分野は特別で、適性があるのとないのとで10倍くらい効率が違うのは当たり前です。だから、適性のない人が寝ずに働いても、適性のある人の足元にも及びません。プログラマに纏わる多くのダークな伝説は、プログラミング好きな適性の劣るプログラマの話です。
プログラミング教育が普及すると、そのような不幸なケースを減らすことができるかもしれません。

プログラミング教育はプログラミングすることではない

小学校で採用が検討されているScratchというプログラミング環境は、ちょっとしたゲームなんかも作れて、楽しいかもしれません。でも、Scratchで作成したソフトウェアは一般社会で通用するようなものにはなりません。Scratchを学んだ先に通常のプログラマになるというキャリアパスは想定されていないと思われます。
ではなぜ、そのような回りくどい方法を取るのでしょうか?一つは、日本語すら勉強中の小学生に、英単語が多数登場する通常のプログラミング言語を教えるのに無理があるので、英単語を使わないScratchなら大丈夫だろう、ということなんだと思います。つまり、苦肉の策としてScratchのようなプログラミング環境が考え出されたわけです。それは極めて後ろ向きの理由です。
別の理由として、プログラム言語ではなくて、プログラミングに付随するプログラミング的な考え方を教育したいということが考えられます。プログラミング的な考え方とは、「できること」を多数組み合わせて、高度な作業を実現する能力です。多くの場合、何かの作業に対して、「やり方」を教わります。作業と「やり方」は1対1に対応することが原則です。ところが複雑な作業では、「やり方」も複雑になるし、複雑な作業は単純な作業より種類がはるかに多くなります。「やり方」を覚える学習法だと、複雑な「やり方」を途方もない数、覚える必要があります。現在の受験システムはそのような「やり方」をいくつ覚えているかをテストする傾向にあります。
すぐにわかることですが、無数にある「作業」に対して一つ一つ「やり方」を覚えるという学習法は非効率です。だから、「やり方」を組み合わせて、複雑な作業に対応するような学習法に移ってゆきます。ただ、それは限界があります。というのも、複雑さが増してゆくと、複雑な作業を例示すること自体が極めて複雑な作業になってくるからです。教材には適しません。プログラミングの学習ではその逆を行います。単純に見える作業を細かい作業に分割し、プログラムという形で再構成します。
よくある作業の例に、インスタントコーヒーを淹れるというものがあります。僕たちはなにげに作業をこなすものですが、手順をきっちり書き下すと次のようになります。

  1. お湯を沸かす
  2. 清潔なカップを用意する
  3. カップに小さじ1杯のインスタントコーヒーの粉を入れる
  4. 必要とあれば粉クリームを適量カップに入れる
  5. カップにお湯をおよそ150cc注ぐ
  6. カップをカップソーサーに置き、ティースプーンと砂糖を添える

いくつかの手順は場合によっては省略できますが、それを省略するかどうかという判断を僕たちは無意識のうちに行っています。プログラミングとは手順を書き下す作業ですから、プログラマにとってはこのような手順を示すのは造作もありません。でも、普通の人にとってはそれほど簡単ではないと思います。例えば、カップを用意してからお湯を沸かすのではなく、最初にお湯を沸かすことで、作業を効率化できます。コーヒーの量を小さじ1杯と具体的に記述することもとても大事です。量を記述する点は、お湯を注ぐ場面でも同様です。これをお客さんに出す場合には、カップの取っ手やスプーンの向きも指定することになるでしょう。
このように、日常生活においても、プログラミングの題材は転がっています。だから、プログラミングを学習するのにプログラミング環境(言語)は必須ではないという考え方があります。それでもあえて、プログラミング環境を使うのは、正解がはっきりするからです。人間相手の手順書では人間が手順書の不備を自動的に補ってしまうので、手順書が不正確であっても問題が顕在化しにくいのです。一方、コンピュータ相手の手順書は不備があると想定した動作・結果になりません。不正解時のフィードバックがはっきりしているのです。その結果、自力で正解を見つけるインセンティブが発生しやすいのです。

プログラミング適性は能力というより性格

僕が見てきた多くの友人・学生の中で、プログラミング適性を持つ人の共通点として、特定の性格・性向を持つということに気づきました。最も重要に思うのは、独立心です。プログラミング適性が認められる人は、何事に対しても自力で取り組もうとする人ばかりです。何か、事に当たるとき、人を集めたり、頼ったりするタイプの人はプログラミングができません。この相関の理由は、プログラミングの作業というのが他人の力を頼れないものだからだと思われます。プログラミングというのは手順を記述する作業です。一度手順を作ってしまえば、二度とその手順のことを考える必要はありません。
多人数での共同作業には2つの種類があります。一つは、作業を「共有」する方法です。すなわち、同じことを多人数で行い、一度にたくさんの成果を得ます。しかしながら、手順がたくさんできてもうれしくありませんので、プログラミングではこの点でのメリットはありません。
もう一つの方法は部分を「分担」する方法です。手順作成を部分に分割するとつなぎ目のところで不整合が起こりやすくなります。なので、分担できる部分は枝葉のように独立している必要があります。本流と支流を整理し、手順作成作業を分割するというのがSEの本来の役割です。それを踏まえても本流の一番難しい部分は基本的に一人が担当します。そういう一番難しい部分をミッションクリティカルと呼びますが、ミッションクリティカルを担当するのは常に一人です。プログラミング適性というのは、そういうことを担当する覚悟ができているかどうか、というのが大事のようです。

覚悟の部分において、プログラミング適性はどちらかというと男性向きの性質のように思えます。しかしながら、女性にもプログラミング適性の高い人が多く存在します。ただし、明白なパターンがあります。それは、女性がしばしば形成する仲良しグループにおいて、絶対的なリーダーか、しりぬぐい役かを担当する人です。
女性は失敗を極端に嫌う傾向があり、何かの共同作業をする際、自分が得意なことを率先して行う傾向があります。多くの場合、円滑に作業が進みますが、難しいパートが残る傾向があります。すなわち、とても難しいパートが残って作業が完成しなくて、途方に暮れる、という場合です。非常に能力の高いリーダーがいる場合、そういう難しいパートをリーダーが無理して担当する場合があります。そのような経験を繰り返すと、自力で何とかするという人格が形成され、プログラミング適性の高い女性が出現すると思われます。そのような人は、リーダーシップにも優れるので、極めて有能なSEあるいはプロジェクトマネージャーになります。
あるいは、性格がよりおとなしい場合、残りものばかりを担当するようになるかもしれません。女性のグループにおいて、残り物の作業は難易度が高いので、いろいろな能力が鍛えられて、優れた能力をもつ人材になります。そのようなしりぬぐいタイプの人も困難な作業に耐えることができるので、プログラミング適性が高くなります。

男性の場合は、内向的な人が多いように思います。内向的で他者の助けを頼みにくい人は、自力で多くの課題をこなす必要があるので、困難に対する耐性が高くなります。ただし、集中力や忍耐も併せ持つ必要があります。内向的であっても、前向きでなければなりません。いわゆる単純なオタクはプログラミング適性が高いとは限りません。プログラミング適性はクリエイティブである必要があるので、既成の何かを集めたりする性向(コレクター気質)とは対極にあります。

プログラミング適性の極端に高い人は、すべての課題を自力解決する性向があるので、他者から頼られることがあります。その場合、一方的に成果を搾取されることになります。搾取を減らすために、友人を減らすような人格が形成される場合があります。通常は、友人の数と課題解決力が直結するわけですが、自分の課題解決能力が友人たちの総和より大きい場合、友人はメリットにはならないという理屈です。極端なプログラミング適性は一般人の100倍以上と言われているので、友人が何人いようと、誤差なのです。
プログラミング適性を持つ人の多くは、他人の言うことを聴かなかったり、対人関係に問題があったりします。そのため、その能力が当人の幸せに結びついている例はまれかもしれません。少なくとも、僕の経験ではそうです。僕は比較的恵まれていますが、そうでない人を多く知っています。経済とか社会の都合で、そのような人を増やそうというのはちょっとどうかな、と思うのです。

誰のためのプログラミング教育か?

プログラミング界のレジェンドDonald Knuthはプログラミング適性のある人は50人に1人と言いました。しかも彼は、受けてきた教育、職業、性別に無関係だと言っています。それはつまり、コンピュータの存在しない時代に生きた人の中にも、プログラミング適性を持つと推定される人物が少なくないということです。Knuthが例として挙げたのは、フーリエ級数で知られるFourierです。Fourierは数学者として知られていますが、もともとは判事です。
Knuthはコンピュータサイエンスの教授ですから、多くの学生と接した経験に基づいた見解です。それはつまり、コンピュータサイエンスを学んだ学生においても、真にプログラミング適性を持つ人は50人に1人だというのです。そして、プログラミング適性を持つ人は、プログラミング適性を持たない人に比べて、最終的に100倍程度のプログラミング能力を持ちます。つまり、プログラミング適性を持たない49人の能力の総和が49に対し、残り一人の能力はその倍に及ぶということです。だから、プログラミングの教育では、一人一人の能力を向上させるのではなく、適性を持つ1人を見つけ出すということが重要だということです。それはもはや教育ではありません。重大なのは、それが、プログラミングを教える教授の見解だということです。
たった2%の人材のために、98%の無駄を許容するのか?というのが本来の議論のはずです。プログラミング適性のある人の能力が100倍に及ぶということは、そうでない人は努力するだけ無駄だということでもあります。

米国で成功を収めている新興企業のCEOの多くがプログラマだという話があります。でもすべてのプログラマが大成功しているかというと、むしろそれは逆です。プログラマでないとCEOとして適切でないかというとそういうこともありません。プログラマというのは、問題解決のための手順の作成に長けた人たちです。つまり、企業活動において特定の問題を解決できることはビジネス上の大きなアドバンテージであり、その方法を考え出すことが成功の秘訣であり、その方法をわかりやすく説明し共有し、大規模展開することが企業活動そのものなのです。それはプログラミング的な考え方が活躍する場面ではありますが、プログラミングそのものではありません。

僕のプログラミング教育法

僕は、これまで何名かの学生にプログラミングを教えてきました。僕が徹底して学生に教えるのは、勉強すべき対象はプログラミング言語ではない、ということです。そのため、僕は原始的なプログラミング言語を選んで使います。そして、最小チューリングマシン定理の話をします。すなわち、基本要素の組み合わせだけで、どんな複雑なシステムも表現できる、ということは、複雑なシステムを学ぶより、基本を徹底したほうが役に立つ、ということです。プログラミング言語における基本要素は、変数・演算・条件分岐・ループ・配列・関数定義・基本入出力(インターフェース)の7つの要素です。文法事項の学習は1時間もあれば終わります。

最初は、ターゲットを絞り込みます。僕は仕事柄複雑な計算を行うので、ループを含む計算がプログラミングの対象になります。ほとんどの計算は、ある種のパターン化されたフレームワークで事足ります。プログラミングの中心は、ループの中に記述する数式になります。だから、プログラミングと言いながら、実態は数式の議論になります。そして、数式を数式のままにしておくのではなく、書き下して数字にすることを考えます。
つまり、プログラムで実現したいことを数式で表し、その数式の具体的な計算法を書き下すということが、プログラミングの中心なのです。それは、確かに、プログラミングではありますが、プログラミング言語は最後の段階に至らないと出てきません。
自分のやりたいことを数式で表現するという部分がもっともプログラミングらしいところです。先のコーヒーの例では、ティースプーンを使ってインスタントコーヒーの粉を計量するという部分が、数式で表現するということに対応すると言うと、わかってもらえるでしょうか。
プログラミングとはプログラムを書くことではないのです。手順を具体的に書き下すことなのです。手順が完成してしまえば、他の人はその手順に従って作業に当たることができます。それはある種のリーダーシップです。しかも、極めて効率的です。ビジネスに対応させれば、優れた経営者となるでしょう。仕掛けが、わかりましたか?

21世紀のビジネス

グローバル化が進むと、言語や考え方が多様化し、会社組織の統率が難しくなります。なるべく単純な言語的手段で具体的な手順を伝えるというプログラミング的なコミュニケーションは、言語のハンデや思想の違いを、楽々と越えます。すなわち、21世紀のビジネスでは、プログラミング的な単純明快さということが、リーダーシップを構成する重要な要素であるということです。それは、忖度とは対極にある考え方です。

問題解決のための手順は自明でないことがほとんどです。効率の良い解決手段を素早く見つけることがビジネスにおける勝負所になります。自明でないというのは、解決手順が複雑ということです。複雑とは、ステップが多いということです。多数のステップをもろともせず、着実に解決に至る手順を見つけ出す能力があれば、ビジネスにおいて勝利の可能性が高くなります。その能力は、プログラマが普段トレーニングしているものです。それはプログラミングを学ぶ理由になるかもしれません。

プログラミングの能力がビジネスで有利であるかもしれないことは認めます。が、それはプログラミング教育を必須化する理由としては十分ではありません。

プログラミングには、適性があり、適性は性格が左右すると考えられます。それはつまり、先天的要素が強いということです。プログラミング教育の必須化は「ふるい」にしかなりません。ふるいによって取り除かれる大多数の立場どうなるのでしょう。あるいは、ふるいによって選抜された子供に対して、適切なケアを考えているのでしょうか?100倍の能力差というのは、他の分野では経験することのない差です。たとえて言うなら、時速3Kmの歩行者と時速300Kmの新幹線くらいの能力差です。大人と子供の差なんてかすんでしまうくらいのものすごい差です。それらを同じ教室にとどめていられるわけがありません。
プログラミングを教えるや否や、適性のある子どもは、あっという間に教師の手に負えなくなるでしょう。当初、文科省は喜ぶでしょうが、圧倒的なタレントの処遇に困るはずです。僕はプログラミングを始めて1か月でゲームを書いていました。そのような子供を適切に教育する方法は今のことろありません。能力を伸ばすには、他の子供たちから隔離して英才教育するしかありません。そのための仕組みはないし、教師もいません。

今のところ、プログラミング教育の導入は、大多数の落ちこぼれと、ごく少数の集団不適合者を産み出すだけの結果になる気がしています。