俺がプログラミング言語を習得できないのはどう考えても俺が悪い！

#はじめに
プログラミングをするためには、当然何らかのプログラミング言語を習得する必要があります。しかし、プログラミング言語の学習がなかなか捗らないという方もいらっしゃるのではないかと思います。
本記事ではプログラミング言語の学習について、個人的にあまり良くなかったなあと思った学習方法をアンチパターン（失敗談とも言う）としてまとめてみます。反面教師としてご活用ください。

また、アンチパターンに対して、どうするのが正解だったのかということについても見解を書いていますが、まだあまり試せてないので話半分で読んでいただければと思います。

## 「習得」とは？
プログラミング言語について、何を以って習得したと言えるのかは難しいところですが、ある程度規模の大きな作りたい物を自力で作れたら、たぶん習得したと言っていいと思います。「自力で」といっても、ググったり本を参照したりするのはもちろんOKです。

# アンチパターン
## その1: 教材の内容を全部覚えようとする
プログラミング言語を学ぶための教材は言語公式サイトのドキュメント、Webの連載記事、入門書、学習動画など色々あります。どれを使ってもいいのですが、私は選んだ教材の中身を全部覚えようと頑張っていました。
たとえば、こういうのです。これを全部覚えようとしてたわけです。
https://docs.python.org/ja/3/tutorial/

しかし、ほとんどの場合は全部覚えるなんて無理ですから、挫折することが多かったです。また、別に覚えなくてもほとんどの場合は問題にならないような細かい内容が含まれている教材もあります[^1]が、そういうのも含めて全部覚えようとしたので、仮に挫折しなかったとしても効率が悪いです。
[^1]: もちろん、それ自体は悪いことではありません。初学者には重荷になってしまうということです。

### どうすればよかったのか
全部覚えるのは無理なので、とりあえずは要点だけ覚えるのがよいでしょう。…と言ってもどこが要点なのかわからないという場合もあると思います。

ここでちょっと思い出話をします。私は新卒で入った会社の研修でJavaを習得しました。研修とは言っても座学ではなく、何も教わらずにいきなり練習問題を渡されました。自分で調べながら解けというわけです。一応Javaの入門書が手元にありましたが、時間がなかったので本の内容を全部読むようなことはできず、とりあえず練習問題をやってみて、不明点があったらググったり本を読んだりしてなんとか解きました。
そのように、教材の内容を全部覚えるようなことはせずに習得したJavaが、今私の主力の言語になっています。

そういうわけなので、他の言語についても同じアプローチをすればよかったのかなと思いました。つまり、教材の内容を理解してから練習問題に取り掛かるのではなく、先に練習問題を見てから教材（の必要な箇所）を参照するというアプローチです。これにより、教材の内容のうち本当に必要な箇所だけを参照することになり、効率よく学習できると思います。
もちろん、「練習問題を解く上ではたまたま必要にならなかったが、本来は覚えなければならない機能」というのもあるかもしれません。そういうのもそのうち覚えなければいけませんが、後回しでいいかなと思います。一応練習問題を解ける程度には身に付けてから読んだほうが効率がよいと思われます。

練習問題ですが、教材に含まれていればそれを使うといいでしょう。ない場合は、「プログラミング 練習問題」とかでググって探してみましょう。とてもありがたいことに、色々見つかります。学習したい言語名を検索ワードに追加するのもよいと思います。[^2]
[^2]: ここで具体例を提示すべきかもしれませんが、私が使ってきた練習問題は社外秘などの理由で提示できないか、もしくはググれば一発で見つかるからあえて提示する必要はないかのどちらかです。

## その2: 規模の大きなプログラムを作らない
私は写経したり練習問題を解いたりすることについてはわりと熱心に取り組んできたのですが、それなりに規模の大きなプログラムを書くということはあまりしてきませんでした。理由はいくつかありますが、最大の理由は、覚えることが多くて尻込みしてしまっていたことです。
たとえばエディタやIDEの使い方、ソースを複数ファイルに分割する方法、依存ライブラリの管理方法、バージョン管理方法、ビルド方法、ユニットテスト方法、などなど練習問題を解くだけの場合とは比較にならないくらい多くの知識が必要になります。[^3]
[^3]: こういった技術は「プログラミング言語」の範疇ではないかもしれませんが、純粋にプログラミング言語だけ覚えても本格的な開発はできません。なので、こういった技術も事実上は「プログラミング言語」に含まれるものとここでは考えています。

しかし、そういった知識は本格的な開発では必須です。私は、業務で使っているJavaはさておき、それ以外の言語については練習問題を解く程度のことしかしておらず、それなりの規模があるプログラムを作らないできたので、結果として上記のような知識はあまり身に付いていません。なので、せいぜいちょっとしたスクリプトを書けるというくらいで、Java以外の言語では本格的な開発はできません。[^4]
[^4]: もちろん、調べながらならできると思います。業務で即戦力になるようなレベルではない、という感じです。

これでは、習得したとは言い難いと思います。

### どうすればよかったのか
まあ見出しの逆を行けばいいわけなので、ある程度規模が大きなプログラムの開発にも挑戦すべきでした。そうすれば上記の通り様々な知識を身に付けるいい機会になりますし、「[その1](#その1-教材の内容を全部覚えようとする)」で書いたような、「練習問題を解く上では必要にならなかったが覚えるべき機能」が必要な場面に遭遇し、その機能を理解する機会にもなるかもしれません。言語の習得のためには、そういった経験が不可欠だと思います。
ついでに、成果物の出来がよければポートフォリオとなって就職や転職に有利になる（可能性がある）というのもメリットかもしれません。

まあ挑戦するといっても、言うは易く行うは難しですよね…
一番いいのは学びたい言語を採用している仕事に就くことですが、それはそれで難しいです。
個人で頑張るなら先述のような周辺技術を一つ一つ調べていくか、もしくはネット上（GitHubやQiitaなど）に真似できそうなリポジトリや記事がないかどうか探すか、もしくは周辺技術も含めて解説している本を探すなどでしょうか。

それと、使用するプログラミング言語についてどれくらい学習してから開発に着手するのか、という問題もあります。ありがちなのは、その言語をしっかりマスターしてから着手しようとすることです。というか私がそうでした。
しかしながら、「[その1](#その1-教材の内容を全部覚えようとする)」と同じで、ほとんどの場合は「しっかりマスター」する前に挫折するのがオチです。
じゃあどうすればいいのかというと、簡単な練習問題を解ける程度身に付いたら、できるだけ早いタイミングで着手するといいと思います。当然、わからないことが多くて最初はなかなか進まないと思いますが、「わからないことリスト」を作って、その一つ一つを調べて潰していけばなんとかなると思います。
「[その1](#その1-教材の内容を全部覚えようとする)」の練習問題を先に読むアプローチと似てますね。練習問題の規模が大きくなっただけと言えるかもしれません。

また、そうは言っても一体何を作ればいいのかわからない、という人もいるかもしれません。というか私がそうでした。せっかくなら役に立つものにしたいとか、すごい物を作ろうとか考えていましたが、それだとハードルが高くて結局着手できないか、投げ出すということが多かったです。
ならば、ハードルを下げればよいはずです。役に立たなくていいし、全然すごくないものでもいいと。アイデアがなければ、既存のツールやWebサービスのクローンを作るという手もあります。手を動かす経験こそが重要なので、成果物は何でもいいと思います。
あとは、こちらのエントリーで提案されている「ログイン機能、画像投稿機能、データダウンロード機能が備わった掲示板」を作るというのもよさそうですね。[^5]
https://axia.co.jp/2018-03-16

[^5]: 私はJavaで作ってみました…が、既に身に付けているJavaじゃなくて、まだ身に付いてない言語でやれよって思いました。

## その3: 学習を継続しない
使わない技術は忘れる…それが残酷な現実です。

どの言語とは言いませんが、社内勉強会でとある言語を勉強することになり、たまたま私が講師役を任されました。私は張り切ってみっちり予習し、どのように教えればうまく伝わるかよく考え、実際に教えて、復習して学習記録を作成し、さらに社外勉強会にも参加するなど非常に熱心に学習しました。しかし、私は今その言語の仕様をあまり覚えていません。社内勉強会で完走したあとはその言語に全然触れなくなったからです。今その言語で何か書けと言われても書けません。

## どうすればよかったのか
せっかくそこまで頑張ったんだから、その後もその言語を学び続けるべきでした。一応、知識を定着させようとして何かを作ろうとはしたのですが、興味が他の言語に移ってしまって投げ出したような記憶があります。

学び続けると言っても、具体的にどうすればいいのでしょうか。やはり、その言語を使ってプログラミングをし続けることだと思います。「[その2](#その2-規模の大きなプログラムを作らない)」の通り何か作るのがベストだと思いますが、他にも単純作業を効率化するためのちょっとしたツールを作るとか、競技プログラミングに挑戦するとか、その言語に関する記事を読んで写経するとか、手段は色々あります。とにかくその言語に触れ続けることが必要だったのかなあと思います。[^6]

[^6]: どれくらいの期間触れ続ければいいのかという問題がありますが…正直なところそれはわかりません。

もちろん、練習問題を解く程度では「[その2](#その2-規模の大きなプログラムを作らない)」の通り本格的な開発に必要な知識は身に付きませんが、それでもやらないよりははるかにマシです。

まあ、その言語を使う機会がなくて忘れてしまうくらいなら、そもそもその言語を学ぶ必要はなかったのでは、という意見もあるかもしれません。でも、やっぱり複数の言語を使えるようになりたいじゃないですか。技術的な興味もあるし、今使っている言語がオワコンになったらどうするのか、というのもありますし。

# まとめ
* 座学はそこそこにして、とにかく手を動かそう
 * 練習問題を先に見て、教材の必要な箇所だけ参照する
 * 練習問題を解くのに必要なかった知識を覚えるのは後回しにする（でも必ずやる）
 * ある程度規模の大きなプログラムを開発する
* 長期にわたってその言語を使い続けよう

# 蛇足
タイトルの元ネタである「わたモテ」は苦手です。観ていて涙が出そうでした。1話の途中までしか観てないけど…