わかりやすいプログラミング入門書だけで学ぶことの弊害

# わかりやすいプログラミング入門書だけで学ぶことの弊害

　わかりやすい入門書はすばらしい。私もそういう本を手にとって、プログラミング言語の全体像を大づかみにとらえる。こうした入門書だけでも、ある程度のものが作れるようになるくらい最近は良い本が多い。しかしここであえてこう言いたい。それらの入門書には共通した欠点がある。
　経験を積んでも、あるときエンジニアは壁にぶつかる。その壁を越えられるか越えられないかの差を生むのは、入門書が与えてくれた方便的説明のわかりやすさが覆い隠している、むき出しのプログラミング言語仕様の奥深さ、コンピュータの動作原理だ。いや、無論そのようなものを意識しなくてもある程度のシステムを不自由なく作っていく事はできる。しかし、それだけではエンジニアとしての成長はいつまでもそこで止まったままだ。

# わかりやすいプログラミング入門書のわかりやすい説明とは

　しかし、上の説明は抽象的すぎて具体的には何を言っているのか伝わらなかっただろう。大丈夫、今から具体例を挙げて説明を掘り下げていく。プログラミング入門書の方便的な説明とは、たとえばこういうことだ。
![変数a.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/362900/12c3d81b-6408-4432-d48b-6d6a11e5ced4.png)
図1. 変数の説明

　誰もがこのような説明を見たことがあるだろうし、聞いたことがあるだろう。
「先生、変数ってなんですか？」「うむ、それは入れ物のことだよ」
　なるほど、そういうことだったのか。と我々はわかった気になる。入れ物、箱、コップ。なんでも良いがそのようなものとして変数をイメージする癖がついてしまう。そしてこう思う。
「ああっ、僕たち、私たちは変数をバッチリ理解したぞ！」

# わかりやすい説明の欠点とはなにか

　わかりやすい説明がダメだと言いたいわけではない。けれどあえて忘れてはいけない問題がある。変数が入れ物であるという説明はあくまでも方便であるということを心のどこかに常にもっておくべきだ。
　それでは説明を続けよう。今、変数aと変数bと名付けた箱の中にそれぞれ「123456789」と「987654321」（注意：数値は別になんでもよい）が入った状態になっているとする。
![代入.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/362900/94bde24b-c7a2-97ff-7322-9a95bc54fb52.png)
図.2 変数aと変数bにそれぞれ任意の数値をいれた状態

　この変数aという名のコップに注がれた「123456789」という名のレモネードと変数bという名のボトルに注がれた「987654321」という名のコカ・コーラを中身を入れ替えなければならなくなったとしたらあなたはどうするだろうか。
　もしあなたが優れたバーテンダーであれば、コップの中身とボトルの中身をすばやく空中に放りだし、落ちてくるコーラとレモネードを元とは逆のボトルとコップで受け止めることもできるかもしれない。だがそれは相当に難しいマジックショーになるだろう。
　そんなわけで通常は、入れ物がもうひとつ必要だという結論になる。
![変数交換.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/362900/6725ef6f-10c2-620b-2be2-70377f838e28.png)

　まず、変数tmpという名のバケツを容易した。そして次のように中身を注ぎ変えていこう。
> ① 変数bの中身を変数tmpに注ぎ込む
> ② 変数aの中身を変数bに注ぎ込む
> ③ 変数tmpの中身を変数aに注ぎ込む

　これで無事、変数aの中身が変数bに、変数bの中身が変数aに移し変わった。この説明は確かにこれでいい。そして変数tmpを用意することはいろいろな意味で理にかなっている。このやり方は正解だと言えるだろう。
　だが、変数tmpは本当に必要不可欠なのだろうか？　変数が入れ物であるというイメージに囚われると変数tmpがなければ、つまり別の入れ物がなければ物理的に中身は入れ替えられないとしか思えなくなる。だが、本当は変数は物理的な入れ物ではないしこれは物理学的な問題でもなかったことを思い出してほしい。

https://github.com/r3d-b3ryl/swap_two_variables
```rb:swap_two_variables.rb
a = -(a + b)
b = -(a + b)
a = -(b + a)
```

このコードを見て何をやっているのか理解できる人はそんなに多くないかもしれない。それどころか数学の方程式か何かにすら見える。だがこのコードは実際に変数aと変数bの整数値を入れ替える。しかも変数tmpを必要としていない。まさに優れたバーテンダーの難しいマジックショーだ。
![swap_two_variables.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/362900/3a4dfecb-e648-cd4d-23c2-216c4fe149d9.gif)
図3. 一時変数を使わず変数aと変数bの中身を入れ替える

　証拠というほどでもないが、上が実行結果である。確かに変数aと変数bの中身が入れ替わったのが分かるだろう。ほかにもこんなやり方もある。これは変数がただの入れ物だと信じてしまっていたらとても出てこない発想だ。

https://github.com/r3d-b3ryl/swap_two_variables
```rb:swap_two_variables.rb
a ^= b
b ^= a
a ^= b
```
![swap_two_variables2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/362900/eb22f80f-eb22-f56e-79bd-94520accf5e7.gif)
図4. 別の方法で入れ替え直して変数aと変数bの値をもとに戻す

　我々はわかりやすいプログラミング入門書の方便的説明、つまり変数とは入れ物のようなものだという説明に囚われるあまり、本来可能な事を技術的に不可能だと思い込んでしまう事がある。その具体例の一つとして、一時変数なしで変数の中身を入れ替えることができないと思えてしまっていたわけだ。だがそれは思い込みである。その思い込みは、わかりやすいプログラミング入門書のわかりやすいイメージに囚われているために生じたのである。
![一時変数なし.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/362900/36841ed8-f810-7537-b0a0-40187cbe6c0b.png)
図5. 変数tmpは必ずしも必要ではない

# まとめ

　繰り返しになるが私はわかりやすい入門書はすばらしいと思っている。私もよくそういう本を手にとって、プログラミング言語の全体像を大づかみにとらえる。しかしエンジニアとして成長しつづけるためには、いつかどこかで、わかりやすい入門書で学んだ知識から脱皮しなければならないことを心に刻んでほしい。
　エンジニアとして壁にぶつかるときその壁を越えるのは、入門書から学んだ知識から脱皮し、壁を飛び越えるための力強い翼を身に着けた者だ。プログラミング言語入門書は、むき出しのプログラミング言語仕様の奥深さへの好奇心、コンピュータの動作原理への探求心に立ち向かうための足腰を培うためのあくまでも手掛かりにすぎないのである。