プログラミング未経験の妻から表題の質問を受けた。それに対する私の回答は「本質的には何でも良い」である。強いて言えば、手続き型の言語で、入門レベルの内容において所謂「おまじない」が少なく、初学者向けの資料が一定程度充実しているもの、さらには、やっていて楽しいものであれば尚良いと思う。
本質的には何でも良い
本エントリの前提として想定する初学者像、即ち上述の「プログラミング未経験の妻」の像は以下である。
- 簡単な英語に抵抗がない。
- キーボードは一定程度扱える。
- コンピュータを専門として深く理解する事を求めているわけではない。
- 今すぐ作りたいものが具体的にある訳ではない。
プログラミング遍歴のエントリ②の中でも書いたが、私は、手続き型の考え方を持つプログラミング言語であれば、大概のもの1は全く未経験のものでも少し勉強すればそれなりに書けるだろうという自信は持っている。実際に数種類のプログラミング言語を扱った事がある、というのもあるが、それらの根底に共通する基本的なプログラミング方法論をある程度は体得出来ている2事が大きいと思う。これが大切な事だと考えている。
プログラミング初学者向けに、やれ最新の言語だの流行りの開発フレームワークだの、これらをやっておけば間違いない、という言説を見かけるが、それにはあまり賛同できない。最新も流行りも常に変化し続ける世界であり、今の流行りが今後もトレンドであり続けるとは限らない。その点でも、身に付けるべきは特定のプログラミング言語やフレームワークに依存しない本質的なプログラミング方法論であり、またアルゴリズム、そしてそれらを組み立てて使いこなす思考力である。それを身に付けるために最初に触れるものが、最新のプログラミング言語やフレームワークである必要は全く無い。勿論、最新のものであってはならない訳では無い。しかし一般に、それら最新のものよりも、登場以来ある程度時間が経過しているものの方が、教材等の充実など初学者向けの教授法が確立されているとすら思う。
その点において冒頭で述べた通り何でも良いだろうと思う。また、こちらもほとんど冒頭で述べた通りではあるが、以下の特性があれば尚良いと思う。
- 手続き型の考え方を持つ。最新や流行りを気にしないとは言っておきつつも、現在様々な場面で使われているプログラミング言語は、手続き型の考え方を持つものが多い。その考え方を押さえておけば幅広に潰しが効く。さらに、広く使われている考え方であるという点から、関数型・論理型の考え方を主軸とする言語と比べた時に資料が多いし、初学者向け教授法の確立という点でも有利と考える。大体、現行のコンピュータ自体、基本的には手続き型のアーキテクチャなのであり、その点でも自然だろう。量子コンピュータ等の話題もあるものの、少なくとも当面は現行のコンピュータアーキテクチャは利用され続けるだろう。
- 「おまじない」が少ない。ここでいう「おまじない」は、プログラムを成立させるために最低限書かなければならないものの、その時々の理解段階ではまだ内容をしっかり説明できないものの事を指す。例えばCの
int main()関数定義は動作するプログラムを成立させるのに必要だが、関数定義の説明をしないとその意味を説明できない。それ以前にintって何、の所から、初見では不明である。他には例えば、Javaのpublic static void main(String[] args)は最近はかなり略記できるらしい3が、それ以前は、このmainメソッドを包含するクラスの定義まで含めて、初学者にとっては訳の分からない「おまじない」であるに違いない。この辺りは、本質的なプログラミング方法論を順を追って理解する際の邪魔になる可能性がある。 - 初学者向けの資料が充実している。これは先にも触れたが、初学者向けの資料が簡単に見つかる程度には浸透している方が望ましかろう。ただ、その手の資料は玉石混交であり、その中から石を退けて玉を選り抜くための審美眼は必要である。問題は、その審美眼はプログラミングを一定程度身に付けてからではないと得られない事である。にわたま。そこで、良い資料を選んだり、場合によっては自分で資料を作る事が、教導者の役割になる。
- やっていて楽しい。何が楽しさとして刺さるかは人によって違うだろうが、楽しい方が当然モチベーションが続きやすかろう。ただ、しばらくやり続けていて初めて見えてくる楽しさもあるので、やり始めてすぐに楽しくないから乗り換える、というのはやめた方が良い。どんなプログラミング言語でも、始めてしばらくの間は覚える事ばかりの割に作れる物の範囲が狭いのであまり楽しくない4ので、取っ替え引っ替えしても効果は薄い。その点、上述の「おまじない」が少ないという事には、楽しさが見えてくるまでの負担を減らすという側面もある。
上述の望ましいと考えられる特性を踏まえると、妻の初めてのプログラミング言語として私からお勧めするのは、Python・JavaScriptあたりの、新興の言語とは言えない程度に長い実績があるスクリプト言語なのかな、という気はしてくる。プログラミング遍歴のエントリ①で触れた通り、私が初めて本格的に触ったプログラミング言語はJavaであったが、上述の特性と比して考えると踏まえるとあまりお勧めできない。
コンピュータを本業にするならCをやるべき
ここまでの初学者像は私の妻、即ちその像は上掲の通り、プログラミングに興味はありつつも、コンピュータを専門として深く理解する事を求めているわけではない、という前提に立っている。一方で、コンピュータやプログラミングをしっかり理解しようと思うなら、Cをやるべきだと思う。最初に触れるべきか否かは難しい所だが、少なくともどこかのタイミングでは必ず。
データ型、ポインタ、配列5、静的・動的メモリ割り当て、そしてそれらを使って作る事ができる様々なデータ構造、等々、コンピュータ上でどのようにデータが扱われているのかを理解するのにCほど分かりやすい言語はあるまい。例えばCにおける配列の考え方、即ち複数の同一データ型の値のためにメモリ上に連続確保された領域、からしたら、スクリプト言語等において配列と呼ばれる物は、実際には配列などではない。後者を実現するためにはどのような工夫が必要であるのか、そしてスクリプト言語等の処理系がその工夫を影でやってくれていたという事が、Cで同等機能を実装してみれば身に沁みて分かるだろう。前節にて、Cを「おまじない」が多い言語の一例として挙げたが、ことプログラム、そしてコンピュータの動きを正しく捉えようと思った時には、Cは極めて単純明快な言語である。その点においては、むしろそれを隠蔽する事でプログラムを書きやすくしている、ここでいうスクリプト言語等を含む最近の言語の方こそ、「おまじない」に満ちている。
ただし、本節冒頭でも触れたが、初学者に対する初手の選択肢にするか否かは悩ましい所である。Cをやった後で、それこそ上述の「隠蔽する」タイプの言語に進む方が、後者が何をプログラマに代わって隠蔽してくれているのか良く分かる。ただ、初学者の最初の言語と考えた時に、Cには先に述べた方の「おまじない」が多いことは否定できない。その点では、まず初手では「隠蔽する」タイプの言語で基本的なプログラミングの考え方を押さえた上で、二番手にCを入れる事で、後に述べた方の「おまじない」を解消していく、というのが落とし所だろうか。
また、ここまでの、コンピュータやプログラミングをちゃんと分かろうと思うならCをやっておけという私の主張は、アセンブラを書く人から見たら、まだまだ生ぬるいのかもしれない。アセンブラ及び機械語のレベルは、Cプログラマから見るとコンパイラによって隠蔽されている訳で。そして更に突き詰めれば、その機械語を処理するCPUの設計・構成、ということになる。どんどん深掘りしていくことで、隠蔽・抽象化のレベルはいくらでも下がっていく。
最早ここまで来ると匙加減の問題である。分かっている方がより望ましいに決まっているが、学習コストは無限に増大するので、どこかでキリを付けないといけない。実際私も、Cより下のアセンブラ・機械語とかCPU設計のような話題になると、多少の知識はあるつもりだが実践の経験は全く無い。で、匙加減の問題というある種の逃げを導入した瞬間に、私のCに関する主張もブレてくる。現在のほとんどのプログラマ6にとって、Cを学ぶという事が、その学習コストと得られる効果の釣り合いが最早取れないものであると認識されている可能性はある。それでも私は、Cを学ぶ意義はあると主張したいが。
結局何から始めるべきか
というような事を考え、結局妻への明快な回答はまだ出来ずにいる。もっとも、妻の場合に限っては、私が教えるという観点から、上述の論点に加え、私の手に馴染んでいるもの、という条件で縛ってしまえば良さそうだが。
悩みは尽きない。
- Brainf*ckなど、意図的に難読性を高めているようなものは厳しい。↩
- こういう事を自ら宣言するというのは謙虚の美徳に反するし、私より余程極めている人など当然のように居る訳で、その点でも心苦しいものがある。しかしそれでも、基本的なものは身に付いてる、くらいは言っても許されると信じたい。↩
- 知識として知っているが、まだ自分で試してみた事がない。最近そもそもJavaを書くことがめっきりなく、先日の自作DIがかなり久しぶりの機会だった。↩
- 何でもいいのでプログラムが動くという事、それだけで楽しさを見出せる人も当然いるにはいる。私自身がその口である。↩
- Cの文脈における配列。↩
- 組み込み系やカーネル周り等の場面を除く、一般的に言われるところの所謂アプリ・ソフトウェアを構築するプログラマを想定する。↩