これはあくまでOpinionである。昨今のプログラミング教育やオンライン学習ツールその他について思ったことを書く。

最初に要約すると、PythonとかJavaとかを〇週間で習得!とかいう広告は何を持って「習得」とするかによるから意味ないし、そもそも日本語(英語)読めれば少なくとも使用することは出来るのだから「使えるようになる」も意味ない言葉だし、○○は使えて○○は使えないとかいう状況もよくわからないし、言語は使うツールであって学ぶものでは無いだろという話。

はじめに

最近PythonだとかJavaとかで某検索エンジンを動かしたり、そこが運営する広告配信によるバナーをみるとやたらとプログラミング言語のオンライン学習教材であったりそれに類するもののプレゼンスが高いように感じる。もちろんこれは広告がパーソナライズされている結果なので誰から見てもそうという訳ではないが。

そこでよく使われるうたい文句に、最速○週間で○○という言語を習得できる!とか現役エンジニアがメンターしてくれる!というものがある。この背景にはその業界における人材不足とその需要に商売の価値を見出した同業種がいて、そこから周りに回って中高の学校教育の場にプログラミング教育を取り入れようとする試みがある。

今でも大学院まで行くと「専門試験」というくくりの項目でもって入試レベルの場でプログラミングの能力が陽に問われることがあるが、それが高校や大学入試の場でも現れるかもしれないとなると危惧すべきことがある。いわゆる受験英語といわれる、本来欲しい英会話に関係の無い能力を入試のためにひたすら磨くことの類似として、受験プログラミングなどが出かねない。

それはそれで一概に悪いこととな言えないにしても、先に述べた某検索エンジンやそこの配信するバナーでプレゼンスが高いオンライン教材はその予兆の一つだろうと見える。

習得の定義

プログラミング言語というものに対して習得という言葉を使っている場合は、まず習得とかいうふわっとした話ではなくて習熟度を具体的にするべき。

習熟度を具体的に示す方法として、何かしらの資格やスコアがあればそれにこしたことはない。英語における英検やTOEICなどがこれに当たる。適当に用意されたカリキュラムを受けることと何かしらの能力が備わることの区別をおろそかにしてはいけない。これは授業をうけることと単位を取ることは違うというのに似ている。

資格やスコアが無いならば可能な限り想定しているレベルを示すべきだろう。しかしそれが難しいというのも分かる。言語仕様の暗記度は習熟度といってよいのか、どこまでが言語仕様であってどこまでがリファレンスを見てわかればよい暗記不要事項なのかの判断が難しい。暗記は本来効率を上げる手段であって、暗記そのものに意味はないということもいえる。調べて出来るなら十分だと。そういう意味で習熟度を測ることは難しい。

何かしらの資格やスコアがあったとしてその内容の質にも無限大の幅があるだろうから一見意味あるのかと思えるが、それらには統一された基準を与えているという意味で内容がどうであれ価値はある。例えば保持スキルを申告する際などに、何の資格なしに書けばそれはあくまで自称習得者にすぎないが資格があれば少なくとも自称ではなくなる。後の項で述べるように言語が何かなんて関係ないんだからAtCoderとかやればいいんじゃないかな。

そもそも言語を習得するというのはしてないの二元的な話ではないというのもあるが、少なくとも○○言語を習得したなどと言われても何をどうできるのかが何もわからないから説明が必要だ。

リファレンス読解力

その言語に特化した能力ではなくリファレンスを解読する能力を同時に磨くべき。

ほとんどの有名言語には間違いなく優れたリファレンスや場合によってはチュートリアルが整備されており、それらドキュメント類の質と量がその言語仕様や処理系の性能以上にその言語のポピュレーションを決めているともいえる。有名言語に加えて最近流行りのという条件は必要かもしれないが多分正しい。メジャーな言語ほどオフィシャルなドキュメントが整っており、逆にマイナー言語はリファレンスやチュートリアルが貧弱で何かしらの前提や察し力が要求される。オフィシャルなドキュメントといっているが、ウェブ上にはいくらでもオフィシャル以外の情報源が存在していてたまに役に立つが役に立たないものもある。

初動でオフィシャルなチュートリアルを十分に活用できるか、その後の使用段階でいかにリファレンスから不明点や未習得の言語仕様を正しく引き出せるかが能力としてより重要である。日本語しか読めないとその人から見えるオフィシャルなドキュメントの量は激減するためリファレンスを飛び回れる英語力は最低限必要。しかし実際は受験英語で十分なのでそんなにここのハードルは高くない。

余談だが英語のリファレンスを日頃から読んでいるから俺の英語力は鍛えられているなどという考え方はやめよう。もともとがよほど読めない人でもない限り一切鍛えられていないといっておく。これは人によっては理解できるあるあるだ。正確にいうとすぐに飽和するのが正しいか。英語は英語の勉強で鍛えよう。

少しだけ知る範囲で個別の事情に目を向けるとC/C++などは言語の「オフィシャル」が所在不明といえるかもしれない。しかしC/C++は有名言語ではあるが最近流行りとはいえるのか?このために最初に最近流行りという条件を付けた。この条件のもとではRustなどに置き換えられるだろう。

何かわからないことがあれば野良犬を存分に活用するのもいい。しかしリファレンスを正しく読み取る読解力を言語の習得に並行して身に着けていくことが結果的に最終的なみなし習熟度の向上につながる。

言語の種類に意味はない

広く一般的なプログラミングという行為に共通する力がより重要だ。

いくら優れた言語仕様やイカした記法があっても根本的に処理の流れをイメージして目的を達成するためには局所的に見てどんな構造の制御構造を用いればよいのかといった力が無ければ腐ったコードしか生まれない。とにかく実装してテストに耐えればいいという考えで量産された腐ったコードが積もりに積もって世の中のパーソナルデバイスのリソースを知らない所でゴミ箱に捨てていく。腐ったコードを吐いているにも関わらずその言語を習得していると思っているのならばかわいそうだ。

最低限のコンピュータサイエンス、特にアルゴリズムとデータ構造についての知識が無ければどうあがいても洗練されたコードは生まれないことは想像が着くだろう。リストと配列のアクセス特性も知らずにどうやって実用的なものを普通に使える用に動かすコードを吐き出せるんだ?

それらの能力と、特定のある一言語の習熟度に何か関係があるかというとそうではないだろう。特にC/C++で適切なアルゴリズムを用いて効率的なプログラムを書ける人ならば十中八九それがPythonだろうとJavaだろうとその言語で出来る最大のパフォーマンスを引き出せるだろう。世の中の書籍タイトル的になぜC/C++のポインタがそんなに難しい扱いをされているのかはわからないが、とにかくC/C++で書けることは十分条件だろう。逆はどうだかわからない。初心者向けだからといってPythonのdictとlistの違いを説明していない講座とか書籍とかは長期的に見て中身が無い。初心者もしくはその人の第1言語であればあるほどそういう説明が何よりも重要だろう。往々にしてそういう書籍・講座に頼っている人は第1言語に近いだろうから高い確率でそういう内容は重要。

関連して少しそれるがC/C++は多少のコンピュータサイエンスを取り入れて説明しなければならない点では優れているともいえる。実行時に可変長配列を用意する面倒くささを知ることが出来るのはCやJavaくらいのものだろう。ところがCやJavaは文末のセミコロンであったり処理系の性能がゆえに強いられていた古い言語仕様なせいで学ばなくていいものまで学んでしまいがちであり、しかも古い書籍のほとんどが最近の仕様変更などを追従できていないのも考え物だ。少なくとも大学授業等のアカデミックな場でC言語の古臭い仕様のレクチャーを他の数学などと同等に扱ったり試験に出してイキったりするのはやめにしよう。

以上をまとめると重視すべきは最低限のコンピュータサイエンス的内容を踏まえた言語習得だ。それさえ説明されていれば題材がどんな言語であれ中身を持ってるといえるが、そうでないならもったいない。

無価値なオブジェクト指向の説明

少し前から思っていたが量産型がオブジェクト指向を学ぶ必要は無い。少なくともその言語を習得したしないの基準にそれら概念の理解度を持ち込むべきではない。

少しそれるがまず絶対にやめるべきなのは害悪なCarクラスを作ること。この例によって分かりやすさが一ミリも増していないしむしろ減少している。言語にビルトインされているようなクラス(例えばFileクラスなどだ、どの言語にもあるだろう)を簡略化して説明すりゃあまだいいのになぜ車載ECUの組み込みプログラムにすら出てこなそうな非現実的なものをクラスの例として取り上げるのか?そういう書籍は今すぐ捨てるかその章を読み飛ばしたほうがいい。

次に言いたいことはもはやprivateによるフィールドの隠ぺいはなんの意味もない。デフォルトでprivateになる時代はもう終わっていることに早く気付くべき。単に値を移すだけのgetterとsetterの例を出しているCarクラスの著者はそうする合理的な理由を説明できているのか?そうでないなら今すぐ(略。抽象的に意図しない変更を防ぐためなどといってprivateなフィールドを持つ利点をいまだに主張するのはやめよう。それでなくてももっとマシな例を使おう。

という文句は一旦忘れる。別にみなければいいだけなのでCarクラスの著者には別に不満は無い。ここで言いたいことはそういう内容を、言語を習得したしないの基準に持ち込むのはどうなのかという点だ。この言語にはクラスの概念があるからクラスの概念やその辺りのその言語における仕様を理解していないとその言語を習得していると言えない、といえるのか?言えないでしょうと。既存クラスの使い方だけ覚えておけばいい。

最近の傾向でいうと人気言語のほとんどは構造化でもオブジェクト指向でも関数型でも扱えるようになっていくのが主流であり、どういう風にその言語を使うかはそれぞれのユースケースによって使い分ければいい。もともとオブジェクト指向とかソフトウェア設計工学とか突き詰めればきりのない項目は言語横断的な話なので、ある一言語を習得していることとオブジェクト指向ができるできないの話は切り分けて考えるべき。

まとめると言語の習得毎にオブジェクト指向の項目をしょーもない例で説明するのは無駄なので差し当たってオブジェクト指向を学ぶ必要は無い。それは似て非なる全く別のカテゴリーの沼だ。

まとめ

長くなったのでこれをまとめるのは至難だ。最初にいいたかったことは特定の○○言語を習得!ということに対する違和感。習得の部分は習得の定義がわからないし、特定の人気言語○○を持ち出している点については根底で必要なプログラミングに関する能力がおそろかにされている印象を持ちかねない。そのプログラミングに関する能力というのはリファレンスの読解力と言語によらないコンピュータサイエンスマターであって、オブジェクト指向はあくまで別ジャンルだからとりあえず放置しておくべきだ。プログラミング言語なんていうものは十分なプログラミング能力の上にのっかっているツールでしかないのだから、○○を習得しているとかどうこうは全く持って重要ではない。

逆もある。教育の現場にPythonが使われているからといって別にそこでPython言語における流儀などを学ばせたいわけではないのだからこれはPythonではこの書き方は不適切どうこうの指摘はナンセンスだ。あれはあくまで見出しはプログラミング教育といっている点で目的はそういうことじゃない。

本当に学ぶべき、習得すべきものって何なの?というのを意見として持った話。

しらんけど

以上は全てしらんけど。意見なので異論も受け付けるし、そもそも受け付ける受け付けない権限なんてもってない。あと暇すぎる。