業務に必要なだけではなく、コンピュータによって問題解決できていない分野を切り開き、エンジニアとして戦っていくため、刺激的な第二プログラミング言語に挑戦しましょう。Rust、Go、Erlang、Elixir、Clojure、Scheme、OCaml、Haskell、Scalaを紹介します。

みなさんが使えるプログラミング言語はいくつあるでしょうか？

ひとくちに「使える」といっても、ひととおりのチュートリアルは終えたという段階もあれば、言語仕様 （あれば） やライブラリを知り尽くしていて、思いついた処理を即座にコード化できるという段階もあります。リファレンスとか参考書を見ながらであれば使える、ということも多いでしょう。

ベテランエンジニアなら、いろいろな仕事に携わっているうちに、さまざまな環境でそれぞれ必要とされる言語をリファレンス片手に使ってきたことでしょう。エンジニアとして働き始めたばかりでも、今まさに業務で書いている言語であれば、胸を張って「使える！」と言えそうです。

世の中には無数のプログラミング言語があり、その数はさらに増え続けています。

シンタックスを覚えているプログラミング言語の数でエンジニアの力量を測るのはナンセンスですが、複数のプログラミング言語を勉強することには、少なからず意味があるでしょう。すでに知っている言語であっても、いままで使ったことがない新しいライブラリやフレームワークに手を伸ばすだけで、見えてくる景色はだいぶ違ってくるはずです。

エンジニアHubでは、これから数回にかけて、IT系エンジニアとして仕事で使っているプログラミング言語ではない言語、つまり第二言語を学ぼうというシリーズ記事を掲載していきます。今回はその第0回として、第二のプログラミング言語を学ぶ意味と、これから学ぶならどんな言語がいいかを考えてみます。

この記事では、いろいろな言語の名前と一行ほどの特徴を紹介していきます。「○○言語の特徴がこの記事だけでは不十分だ。○○言語を学ぶべき理由はもっとたくさんある！」という方がいらっしゃいましたら、これから新しく勉強してみたい人向けに、○○言語のアピールポイントや最適な学習素材などをブログなどで紹介してみてください。

なぜ第二言語を学ぶの？

仕事で使うプログラミング言語が決まっている方も多いでしょう。その言語をとことん突き詰めるのもいいかもしれませんが、ここでは複数のプログラミング言語を学ぶ理由を考えてみましょう。

楽しいから！

第二のプログラミング言語を学ぶ理由として、まっさきに挙げたいのは、「楽しいから」です！

自分が知らない世界へ足を踏み出すときのわくわく感、知識欲が満たされるときのじっとしていられない感覚。海外旅行に行くような気分で、何でもいいから第二のプログラミング言語に挑戦してみるというのは、すでに何らかの言語でプログラムを書いたことがあるエンジニアだけに許された贅沢だといえるでしょう。

作りたいアプリケーション、やりたい仕事に必要だから

作ろうとするアプリケーションによっては、第二言語や新しいフレームワークの勉強が必須になります。

自分がいま使える言語がVB .NETだけだったとして、macOSで動作するアプリケーションを書く必要があるなら、SwiftやObjective-Cを学ぶしかないでしょう。逆に、Apple製品向けのアプリを書いている人が、Windows向けアプリを書く必要があるときはC#やVB .NETを、Android向けアプリを書く必要があるならJavaやKotlinを学ぶことになります。

必須ではないけれど、自分がいま知っている言語でがんばるよりも新しい言語を覚えてしまったほうが楽、ということも少なくありません。たとえば、いま使える言語がRubyだけだったとして、機械学習に手をつけたいと思ったなら、RubyでがんばるよりPythonを学ぶほうが近道のはずです。

JavaScriptでWebアプリを書けるけど、Unityで作りたいものがあるから、この機会にC#を勉強してみよう、といったケースもありでしょう。

キャリアのための生存戦略として第二言語を選ぶ

第二のプログラミング言語を学ぶことには、楽しみとしてだけでなく、実用的な利点もあります。

プログラミング言語まわりでは、「いま○○が熱い」「これからは○○だ」という話がとにかく絶えません。まったく新しいプログラミング言語は次々に生まれていますし、言語としては同じでもバージョンが変わって昨日まで使っていた構文が廃止されたり、新しいフレームワークやライブラリが登場したり、聞いたこともないような概念が提唱されて実装されたりします。

どのプログラミング言語を習得しているか、どんなフレームワークの経験があるかによって、エンジニアとしてのキャリアが左右されるように感じることもあるでしょう。いま自分が使える言語やフレームワークだけで、生涯にわたって仕事が続けられるとは限らないのが現実です。

この先も同じ道具一本で続けられるとは限らないなら、注目されていて需要も多いプログラミング言語やフレームワークに挑戦していく。自分が次に学ぶプログラミング言語をこの方向で考えるなら、これから需要が増えそうな言語を学ぼうといえるかもしれません。

これから需要が高まるプログラミング言語を予測するのは簡単ではありませんが、たとえば次のような「世界的に人気のあるプログラミング言語」を表すランキングが参考になります。

転職に有利な第二言語が見つかるかもしれないランキング TIOBE Index https://www.tiobe.com/tiobe-index/

さまざまな検索エンジンでよく検索された言語のランキング。

みんながいま知りたい言語のランキングともいえるが、「○○ language」のようなキーワードで検索された回数なので、「英語圏の人がlanguageを付けないで検索しても困らない言語」は目立ちにくい傾向がある （ScalaやErlang、Haskellなど） 。 RedMonk Programming Language Rankings http://redmonk.com/sogrady/2017/03/17/language-rankings-1-17/

GitHubのプルリクエストの件数と、Stack Overflowのタグの数を、二次元にプロットしたもの。

もともとはGitHubのプロジェクト数とStack Overflowのタグ数の相関を求める目的だったが、現在では各言語の人気度をコードとコミュニケーションの両面で表したランキングとして、年に二回発表されている。

もっとあからさまな指標として、転職サイトの募集要項で求められている数が多い言語や、募集給与が高い言語を調べるという方法もあります。各求人サイトで人気言語のランキングが発表されていたりするので、興味がある方は「転職 言語 人気」のようなキーワードで検索してみてください。

第二言語を学ぶ本当の意味

ここまで、第二言語を学ぶのは楽しくてキャリアにも役立つからという、わりと当たり障りのない話を書いてきました。でもこれって、第二言語に限らず、何か新しいことを学ぼうというときには必ずといっていいほど当てはまる話ですよね。

勉強は、すぐに結果を出す必要がなければ楽しいし、それが生き残りをかけた勉強であるなら、楽しいとか楽しくないとか関係なくやるしかありません。

そこでこの記事では、第二のプログラミング言語を学ぶという点に話を絞って、もうちょっと別の考え方を提案してみたいと思います。それは、

目先の仕事や近い将来の転職に直接役立つかどうかはなんとも言えないけれど、いまの自分には思いもよらない課題に対してもコンピュータを使って問題解決ができるように、第二言語、第三言語に手を出してみよう

というアプローチです。

現在の業務や、近い将来の転職に直接役立ちそうなプログラミング言語やフレームワークを勉強することは、すでにコンピュータで解決できる課題であることが判明している問題への対応です。

しかし、コンピュータを活用したエンジニアリングが切実に求められていて、それゆえにエンジニアの市場価値がこれから高くなる可能性を秘めているのは、まだコンピュータによる問題解決に手がつけられていない分野、それどころか、まだコンピュータを活用して解決できる問題として認識されていない分野かもしれません。

そのような分野を切り開いていくツールとして未知のプログラミング言語に手を伸ばしてみるのは、よりいっそう刺激的な挑戦といえるのではないでしょうか？ しかも、そうやって学んだ刺激的な第二言語は、いつもの業務で思わぬ効果を上げる可能性もあるはずです。

「ハンマーしか持っていなかったら、なんでも釘に見える」という戒めがありますが、第二言語を学ぶことは、まさにハンマー以外の道具を持つことだといえます。

ただし、これは、新しくて便利なツールを道具箱に増やしていこうという意味ではありません。新しい道具を手にする最大の利点は、それまで見えていなかった課題に気づけることです。ハンマーにしても、それまでハンマーを持っていなければ、そもそも釘が見えていない可能性があります。

ハンマーを手にしたことで、「いままで釘だと思わなかったものが実は釘であったことに気づく」ことだってありえるのです。求人が多いわけでもないプログラミング言語をわざわざ学ぶことは、この意味で新しいツールを手にすることかもしれません。

ポインタと再帰を意識できる言語を学べ（by Joel Spolsky）

というわけで、ここからは、短期的なキャリアアップにつながるとは断言できないけれど強力なツールとして学ぶべき第二言語について、少し思いを馳せてみましょう。

具体的な言語について考える前に、学ぶべきプログラミング言語を見極めるときのヒントになりそうな記事を1つ紹介します。かつてMicrosoftでExcel VBAの開発に携わり、現在ではStack OverflowのCEOでもあるJoel Spolsky （ジョエル・スポルスキー） 氏が、いまから10年以上前の2005年末に公開した「Javaスクールの危険」という記事です。

ものすごくざっくり要約すると、「Javaだけを学んだプログラマーは、優れたプログラマーかどうかわからない」というのが、この記事におけるJoel氏の主張です （短い記事なので、ぜひ全文を読んでください） 。

Joel氏は、その主張の根拠として、記事中で次のように言っています。

ポインタと再帰を理解できる能力は、優れたプログラマになるための能力と直接的に相関している。

Joel氏は、言語によってはポインタや再帰を意識せずにプログラミングできることがウリになっていて、Javaがまさにそのような言語だと言います。実際、仕事でプログラムを書くツールとして考えれば、ポインタや再帰の意味を理解しなくても使える言語のほうが、間違いなく実用的な言語でしょう。

しかし、ソフトウェア開発についての教育という観点では、ポインタと再帰を意識しなくても済むプログラミング言語は不適切であり、まるでスプーンでご飯を食べさせてあげるようなものであるとJoel氏は言います。彼の見解に従うなら、学ぶべきプログラミング言語とは、ポインタや再帰を意識せざるをえない言語ということになりそうです。

プログラマーとして闘うために必要な力をつける言語を学ぼう

Joel氏の主張を真に受けて、第二言語としても、ポインタと再帰を極めるような言語に挑戦していけばいいのでしょうか？ プログラミングの筋力は確実にアップしそうですが、それだけでは現代的なソフトウェア開発の武器としてはやや心もとない （原始的すぎる） 気もします。

そこで、Joel氏の主張を少し幅広く解釈して、優れたプログラマーとして闘うために必要な力を次のように言い換えてみたいと思います。

コンピュータシステムにおける 情報の表現 を意識できる力 （Joel氏の言葉では「ポインタ」）

を意識できる力 計算機科学に根差した強力な抽象化を使いこなす力 （Joel氏の言葉では「再帰」）

以下では、この2つの側面のそれぞれについて、学ぶべきプログラミング言語としてどんなものが考えられるかを無理やり紹介してみます （実際には、何らかのプログラミング言語がこの2つの側面のいずれかだけにきっちり対応しているわけではないので、「無理やり」です） 。

「コンピュータシステムにおける情報の表現を意識できる力」を引き延ばす

プログラミングとは、現実世界の問題を理解し、それをコンピュータで扱えるようにする行為です。コンピュータで問題を扱うからには、現代のコンピュータが情報を扱っているやり方を理解する必要があります。そのやり方を知るには、メモリやネットワーク、OSやファイルシステムといった、コンピュータシステムに近い部分に触れてみるのが一番でしょう。

プログラミング言語には、そのようなシステムプログラミングに向いた言語と、もっと上位のアプリケーション開発に向いた言語とがあります。システムプログラミングを体験するのに向いた言語として、過去にはC/C++というのがほぼ唯一の選択肢でしたが、最近ではRustやGoといった新しい言語も登場して利用が広まりつつあります。

これらは、学ぶべき第二言語の有力候補になりそうです。

アプリケーションプログラミングでも、非同期メソッドやマルチスレッドを活用する場合には、コンピュータシステム上でプログラムがどのように実行されるかを意識することがとても重要になります。

古典的な言語であれば、ロックを用いて競合状態を自分で管理する複雑な方式を勉強する必要がありますが、最近ではメッセージパッシングやSTM （Software Transactional Memory） などに対応した現実的な言語が多数登場しています。

そのような並行モデルを特徴とする言語として注目されることが多い、ErlangやElixir、Clojureを第二言語として学んでみるのも面白いでしょう。

なお、すでに紹介したRustとGoにも、それぞれ並行・並列プログラミングを書きやすい仕組みが用意されています。また、JVM上のAkka | Akkaというフレームワークでも、Erlangに似た並行プログラミングのモデルを学ぶことができます。

「計算機科学に根差した強力な抽象化を使いこなす力」を引き延ばす

プログラミングでは、コンピュータへの命令が上手にできるだけでなく、そもそも現実世界における問題をうまく理解する必要があります。この点について、Joel氏は「再帰」が重要と言っていますが、これは、現実世界の問題には木構造やグラフ構造として表せるものも多く、そうした構造を扱う自然な方法が再帰的なアルゴリズムだからであると考えられます。

再帰は、いわゆる関数型言語で多用されるので、SchemeやHaskell、OCamlなどを通して学ぶのが手っ取り早いといえそうです。これらの言語を学ぶことで、関数などのブロックの中で自分自身を呼び出す明示的な再帰だけでなく、mapやfoldといった高階関数の利用にも慣れることができます。

再帰だけではありません。解決したい課題があるときは、まず関係するモノを分類して、問題を定式化する必要があります。そのためのうってつけの道具として「型」があります。

型は、計算機科学でしっかりと理論付けされているので、人間が考えたモノの分類を、コンピュータでも破綻なくよろしく扱ってもらえるような仕組みが作れます。CやJavaでしか型に触れたことがないと、人間がコンピュータに合わせるために書かされている面倒なもの、という印象しかないかもしれません。しかし、実際には、現実の問題をうまく整理してコンピュータに扱わせる便利な道具なのです。

OCaml、Haskell、Scalaのような、柔軟で性質のよい型システムを持つ静的型付き言語を1つでも突っ込んで勉強してみると、普段のプログラミングに対する考え方もかなり変わるかもしれません。

関連記事

第二言語として学ぶべきプログラミング言語の名前をいくつか具体的に出してみましたが、これらの言語のうちElixir、Rust、Haskellの3つを取り上げて、次回から順番に紹介していきます。言語の雰囲気を紹介するだけでなく、簡単なチュートリアルもお届けする予定です。

第一弾は、分散・並行プログラミングでは鉄板の基盤であるErlang仮想マシン上で、アプリケーション開発言語として一気に利用者が広がったElixirです。Elixirを業務で導入しているドリコムの大原常徳さんによる言語紹介と簡単なチュートリアルを予定しています。

お楽しみに！

第二言語としての……シリーズの記事一覧

執筆者プロフィール

鹿野桂一郎 （しかの・けいいちろう、GitHub、Twitter）