ひとりでプログラミングを学ぶうえで役に立った(と思う)こと

休みの間にRustで遊んでいた。新しい言語を触るのが好きなので、いままでいろいろ試してきたが、あらためて振り返ってみるとこの趣味はひとりでプログラミングを学ぶうえでとても効果的だったと感じた。

Javaが私のはじめての言語だったが、ループは変数を加算(減算)することで定義することが多かった。拡張for文のようなスマートな方法も本で読んだが当時はよくわからなかったので、もっぱら「i」をインクリメントしてループを書いていた。

JavaのつぎはPythonを触ってみたが、Pythonでは変数をインクリメントして行うループがなかった(私が知らなかっただけかもしれない)。そのかわりにデータの塊をひとつずつなめるような形でループをするらしく、単純にn回繰り返したいときはrange()という関数を使って書くというのが最初はかなり戸惑った覚えがある。

その後いろいろあってOCamlを触ってみると今度は再帰を使ってループを書くのが「関数型っぽい」とのことだった。OCamlにはほかの言語のような命令的なfor文もあるが、再帰のほうが「クール」な気がしたので、コードをぐちゃぐちゃにしながら再帰で2重のループをがんばって書いた。ループというプログラミングの基礎中の基礎でも、いろんな言語を触ってみることで考え方の幅が広げることができたと思う。

OCamlは触りはじめたころにバリアントがまったく理解できずかなり悔しい思いをしたが、そのあとにElmを触ったときに、すっと腑に落ちたことがあった。Elmではモデルを更新するためのメッセージという形でバリアントと同じようなものが出てきて、「こんなに便利なものだったのか!」と感動した。

「最初に学ぶ言語は何がいいか」という問いに対して「なんでもいい」、あるいは「(できれば)まわりに教えてくれる人が多いものがいい」というのが一般的な答えらしい。プログラミングをはじめたころは、「何をやるのがいいのか」ということがとても気になっていたが、最近になって言わんとすることがわかるような気がしてきた。言語によっていろいろ違うところはあれど、登場する概念はどの言語でもだいたい同じようなものだから、そこにこだわる必要はあまりないということなのだろう。

環境構築もJavaをはじめたときはそれだけで挫折しかけたが、何度もやっていれば基本的には「処理系を置いてパスを通す」というだけのことだとわかった。それでも最初は「JAVA_HOMEを設定して、JDKのパスを通す」というのが何を意味するのかわからず絶望的な気持ちになったことを覚えている。

馴染みがなくてよくわからない概念でも、いろんな文脈、使われ方で接していれば、そのうちなんとなくでも意味がわかるような気がしてくる。私はまわりにプログラミングを教えてくれる人がいなかったので、ifが式だったり文だったり、実行する前にコンパイルが必要だったりいらなかったりと、いろんなことを経験するからこそ理解できたこともあったのだと思う。

残念ながらこれは趣味なので、いまでもまともに書ける言語は2、3個しかない。そもそもチュートリアルを一周してAtCoderのAとBをいくつかやったら満足して終わってしまうことが多い。しかし情報系の教育を受けなかった自分がプログラミングをひとりでやっていくためには、同じような概念をいろんな文脈で学ぶことは効果的だったとRustを触っていて感じた。

腰を据えてひとつのことを突き詰めるというのも必要だと感じるが、こうした勉強のやりかたも悪くはないように思う。