プログラマーSEはプログラミング言語をいくつ覚えればいいか?
プログラミングの達人というと、いくつもの言語をマスターしていて、必要に応じて使い分けているようなイメージがありますよね。
実際は、達人というほどでなくても、複数のプログラミング言語を使える人はたくさんいます。
私自身もそうなんです。仕事で使ったものだけでも、Java, JavaScript, C#, PHP, Perl, C言語, PL/SQL, VBA, COBOLとけっこうな数あります。
趣味で使ったもので言うとRuby, Node.js, C++, MQLがあります。
「こんなにたくさんの言語を使えるなんてすごい!」と思われたかもしれませんが、案外ふつうのことです。あなたにもきっとできます!
プログラミング言語ってどれもよく似ているので、方言みたいなものなんです。
東京生まれの人でも、テレビで関西の芸人がしゃべっているのを真似して「なんでやねん」とか、えせ関西弁を話せますよね。本気になれば、えせじゃなく全部関西弁のイントネーションで話すこともできるはずです。
複数のプログラミング言語を使えるようになるのも同じようなものです。
先程のえせ関西弁と同じでプログラミング言語をちょっと使える程度になる「えせ状態」にならかんたんになれます。そこから、プロとしてお金をもらえるレベルになるにはもう少し努力が必要になりますが、努力と言っても英語をマスターするのに比べればずっとずっとかんたんです。
では、本題である「いくつ覚えればいいのか?」について考えていきましょう。
一つでもいいけど…、
究極を言ってしまえば、いくつでもいいんです。
「おれは一つの言語を極める!」と決めて、その言語のスペシャリストになっていくのもありです。
ただ、その言語の需要がなくなってしまった場合、職業プログラマーとしては困ってしまいます。とはいえ、実際、それまでにある程度需要のあった言語の需要がゼロになることはなかなかありません。COBOLだって未だに需要があります。
仮に需要がなくなったとしたら、その時に別の言語を覚えればいいので、それほどの問題ではありません。
言語には系統の近さがある
プログラミング言語の違いは方言みたいなものだと言いましたが、とはいえ、似てる度合いが近い言語、遠い言語があります。
自然言語でも、
- 英語とドイツ語は単語や構文規則が近い
- 日本語と文法が近いのは韓国語
と言われてます。
これと同じようにプログラミング言語にも系統があります。
例えば、C言語系統の言語として、C言語の子供として、C++があり、さらにその子供にJavaとC#がいます。PerlやPHPもC言語系統の言語です。
これらの言語は一つ覚えれば、他の言語を覚えるのもかんたんです。文法やキーワードがほとんど同じだからです。
例えば、Javaのif文と代入文は以下のようになります。
if (val == 2) { num = 5; }
PHPだと以下のようになります。
if ($val == 2) { $num = 5; }
ほとんど同じですよね。PHPの場合、変数の頭に$をつけますが、それ以外はほぼ同じです。
これに対して、別系統の言語であるCOBOLを覚えるのは少し大変です。
IF val = 1 THEN MOVE 5 TO num END-IF.
「え?」って感じですよね。とはいえ、これは短いコードサンプルなのでなんとなくは分かるかと思いますが、C言語系統の言語では変数への代入を
num = 5;
と数式のようにイコール(=)使っているのに対して、COBOLは
MOVE 5 TO num
と英語のような書き方になっています。このように基本的な表記方法に違いがある言語を覚えるのはちょっとだけ大変です。
そして、主要な言語の中でCOBOLのような表記をしているのはCOBOLだけです。
ですから、COBOLしかわからない人は他の主要な言語を覚えるのに苦労することになります。
複数の言語を学ぶと視点が一つ高くなる
複数の言語を覚えると、複数言語にまたがるプログラミングの本質が見えてきて、視点が高くなります。
「Rubyでは高階関数を使った書き方が多用されてるなぁ、それならPHPを使う時にも高階関数を使った書き方も試してみよう」
という風に、他の言語で学んだプログラミングテクニックを別の言語に応用できるようになります。
これって一つの言語しか学んでない人にはできないことです。
いくつもプログラミング言語を学んでいくと、どんどん言語間の共通点が見えてきます。すると、プログラミング言語ってこういうものだよなという、本質のようなものが見えてきます。
すると、新たに言語を覚える際にも、それらの知識を使ってすばやく習得できるんです。
自然言語でも同じで、英語を学んだ後にドイツ語を学ぶのはかんたんになりそうですよね。その後、フランス語を学ぶのはさらにかんたんでしょう。
というように、学べば学ぶほど、次学ぶのが楽になるという好循環が生まれます。
ですから、少なくともプログラミング言語は2つ以上学んだほうがいいと思います。
そして、できたらパラダイムの違う言語を学ぶべしとも言われています。
プログラミング言語のパラダイムとは?
言語のパラダイムには以下のようなものがあります。
- 手続き型言語 → C言語, Pascal, FOTRAN, COBOL
- オブジェクト指向言語 → Java, C#, Ruby, PHP, Python, Perl, JavaScript
オブジェクト指向言語の中にも大きく分けて2つのタイプがあります。
- クラス型オブジェクト指向言語 → Java, C#, Ruby, PHP, Python, Perl
- プロトタイプ型オブジェクト指向言語 → JavaScript
↓クラス型オブジェクト指向言語(PHP)のサンプルコード
//クラス定義 class Hello { function sayHello() { echo "Hello World"; } } //実行 $hello = new Hello(); $hello->sayHello();
↓プロトタイプ型オブジェクト指向言語(JavaScript)のサンプルコード
//プロトタイプ定義 function Hello() { this.sayHello = function() { console.log("Hello World"); } } //実行 $hello = new Hello(); $hello.sayHello();
けっこう違いますよね。プロトタイプ型の場合、オブジェクトをnewした後にメソッドを追加することもできます。
$hello = new Hello(); $hello.sayHello(); // Helloオブジェクトをnewした後に、メソッドを追加 $hello.sayGoodNight = function() { console.log("Good night"); } // 追加したメソッドを呼び出す $hello.sayGoodNight();
このような様々なタイプの言語を学ぶとタイプごとに特徴的なプログラミング哲学があって、それらを学ぶことによって、プログラミングをする時の発想の幅が広がります。
とはいえ、上記で紹介した言語は大きなくくりで言うと「命令型言語」です。
そして、もう一つのパラダイムとして関数型言語というものがあります。
命令型言語と関数型言語の違いは大きい
命令型言語は、命令を一つずつ順番に実行していくことで処理を進めますが、関数型言語は関数を連鎖させることで処理を進めていきます。命令型言語でも関数を定義できるので、関数を連鎖させるロジックは書けますが、基本的な考え方が異なるんです。
例えば関数型言語であるHaskellでFizzBuzzのプログラムを書くと以下のようになります。
fizzbuzz :: Integer -> [String] fizzbuzz 0 = [] fizzbuzz n | n `mod` 15 == 0 = fizzbuzz(n - 1) ++ ["fizzbuzz"] | n `mod` 3 == 0 = fizzbuzz(n - 1) ++ ["fizz"] | n `mod` 5 == 0 = fizzbuzz(n - 1) ++ ["buzz"] fizzbuzz n = fizzbuzz(n - 1) ++ [show n]
「なんじゃこりゃ?わけわからん!?」ってなりますよね。
FizzBuzzとは、
- 引数が3で割り切れる場合は「Fizz」
- 5で割り切れる場合は「Buzz」
- 15で割り切れる場合は「Fizz Buzz」
を返すプログラムです。
プログラムの仕様が分かってもHaskellのコードって「は?」って感じですよね(笑) 関数型言語は命令型言語とは根本的な考え方が異なるので命令型に慣れたプログラマーにとって理解がとても難しいんです。
同じプログラムを命令型言語であるPHPで書くと以下のようになります。
function fizzbuzz($i) { if ( $i % 15 == 0 ) { return 'FizzBuzz'; } else if ( $i % 3 == 0 ) { return 'Fizz'; } else if ( $i % 5 == 0 ) { return 'Buzz'; } else { return $i; } return "n"; }
「これなら分かるわいっ!」ですよね(笑)
言語学習に失敗しない秘訣
私も関数型言語に何度もチャレンジしては、敗れてきました。
なんでかというと、関数型言語で作りたいものがなかったからです。関数型言語の考え方を学ぼうと思って、入門書を何冊も読んだのですが、全然身につきませんでした。勉強のための勉強ってやっぱりうまくいかないようです。
ですから、パラダイムの違う言語を「勉強するために勉強する」のではなく、パラダイムの違う言語を使って「何かを作りたくなった時に学ぶ」のが良いと思います。
まとめ
- 主流な言語は皆似てるので、2つ以上学んでプログラミング言語間の共通点 = 本質を学ぼう
- パラダイムの違う言語を学ぼう(勉強のための勉強にならないように、学ぶ目的ができてから学ぼう)