プログラミング言語の習得難易度を分類してみた
「できれば習得がかんたんな言語が良いな!」
「就職・転職で評価される言語は?」
どのプログラミング言語を学ぼうか考えるのって楽しいですよね?
私もこれまでC言語, C++, JavaScript/node.js, Visual Basic, Java, PHP, Ruby, C#と様々な言語を使ってきました。
ちょびっと触った言語としてPython, Perl, Scala, PL/SQL, COBOL等があります。
入門書は読んだけど、実際使うには至らなかった言語(Haskell, F#, Common Lisp, Clojure, Lua, Go)もたくさんあります。
そんな経験を踏まえて、プログラミング言語の習得難易度を分類してみます。
難易度S(全くものにならず)
Haskell, F#, Common Lisp, Clojureです。つまりは関数型言語ですね。
入門書を読んで文法を頭に入れてみたものの、これらの言語を使って「何か作ってみよう」という気になれませんでした…。
というか、どのようにロジックを組むかの発想が全く浮かばなかったんです。
「関数型言語を使ってこういうものを作りたい!」っていう具体的な目的がなく、勉強のための勉強になっていました。
- プログラミング言語は使わないと身につかない
- 関数型言語で何かを作る発想が浮かばないため使う機会がない
というデッドロック状態だったんです。
難易度A (難しいけど、頑張れば使えた)
C言語, C++です。低水準な(ハードウェアに近い)言語という意味での難しさがあります。
私は18歳の時に専門学校に入学してプログラミングを始めました。その時に習ったのがC言語とC++なんです。
「今思えば難しい言語だな」と感じます。
特にC言語は用意されてる標準関数が簡素な機能しかなく、「原始的なロジックを自分で組む練習」になりました。
JavaやC#、PHP、Rubyなど、C言語より高水準な言語に慣れ親しんできた今、あらためてC言語でコードを書くのはしんどいです。例えば、C言語にはString型がないため、char配列を直接操作するコードを書かなければならないんです。出来ないこともないけど、めんどいですよね。
「ポインターが難しい」って話がよくされますが、そこまで特別なものでもありません。ポインターって、ざっくり説明すると他の言語でいう「参照」の一種なんです。
参照はオブジェクトのアドレスです。ポインターもアドレスです。
ポインターの場合、アドレスに加算減算などをして参照する先を移動させることができます。違いはそれだけなので、知識として理解するのはそこまで難しくありません。
ただ、知識として分かっていても複雑なポインタ演算を使ったコードは「書いた本人以外よく分からん」ってことがよくあります(笑)
難易度B (かんたんに見えてしんどい)
JavaScript/node.jsです。意外ですかね?
メジャーな言語の多くは同期IOを基本にしているのに対してJavaScriptは基本的に非同期IOなので、コールバック関数でIO(入出力)の結果を受け取る書き方をしなければならない所がやっかいなんです。
PHPでファイルを読む同期IOのコードって以下のような書き方をします。
$data = read($filename); // $dataを使った処理を書く...
同じことをJavaScriptで書くと、非同期IOなので以下のようになります。
read(filename, function(data) { // dataを使った処理を書く... });
非同期IOだと、IOが発生する度に無名関数を書いて結果を受け取らなければならないんです。IOが一回ならいいけれど何度もあるとやっかいです。
例えば、3個のファイルを読むが場合、こうなります↓
PHPの場合、単純に3行コードを書くだけです。
$data = read($filename); $data2 = read($filename2); $data3 = read($filename3);
ところが、JavaScriptの場合こなります。
read(filename, function(data) { // dataを使った処理を書く... read(filename2, function(data2) { // data2を使った処理を書く read(filename3, function(data3) { // data3を使った処理を書く }); }); });
コールバック地獄ってやつです。コールバック関数が何重にもネストしてコードが読みにくくなります。Promiseという仕組みを使えば多少は読みやすく書けますが、それでも同期IOのコードに比べると複雑です。
ですから、脳に負荷のかかる言語だと思います。まぁ、修行になっていいかもしれないですけどね。
それから、オブジェクトを定義するのがクラスではなく、プロトタイプなのも特殊です。
メジャーなオブジェクト指向言語はクラス型オブジェクト指向なのに対して、JavaScriptはプロトタイプ型オブジェクト指向なので、他の言語の考え方をそのまま使うことができず、これまた脳に負荷がかかって修行になります。
例えば、PHPでオブジェクトを定義する場合、クラス型オブジェクト指向なので以下のようになります。
class Dog { public $name = ''; public function bark() { echo $this->name . 'です!ワンワン!'; } } $dog = new Dog(); $dog->name = 'ポチ'; $dog->bark();
JavaScriptでオブジェクトを定義する場合、プロトタイプ型オブジェクト指向なので以下のようになります。
function Dog() { this.name = ''; this.bark = function() { console.log(this.name + 'です!ワンワン!'); } } var dog = new Dog(); dog.name = 'ポチ'; dog.bark();
classの方が直感的で分かりやすいですよね。
node.jsをしばらくやった後、PHPやRubyに戻ると、
「なんて楽なんだー!同期IOさいこー!classさいこー!」
って思えます。
とはいえ、JavaScriptは言語仕様がコンパクトで覚えるべき基礎知識も少ないので、入門しやすい言語でもあります。入門はかんたんなので、初歩の知識でしばらく使って、次のレベルへと上がるためにもう一度深く学ぶのがいいと思います。
難易度C (ふつうに使える)
Java, C#, PHP, Perl, Python, Ruby, Visual Basicです(その他大抵のメジャー言語Swift, Go, Kotlin等もこのランク)。
「えっ?PHPの方がJavaよりかんたんなんじゃないの?」
と思われたかもしれませんが、大きなくくりとしてのPHPとJavaの難易度は変わりません。
これらの言語は皆、
- クラス型のオブジェクト指向言語、かつ命令型言語
です。基本はみんないっしょなので、文法の差異を学ぶだけですぐ使えるようになります。
命令型言語は基本的に、
- 逐次実行 → 上から順番に実行される
- 分岐 → ifやswitchで分岐
- 繰り返し → forやwhileで繰り返す
の三要素でできているので、これを抑えればどの言語も使えます。
もちろん、その言語らしい書き方ができるようになるにはそれなりの時間を要しますが、それでも、関数型言語のようなパラダイムの違う言語を覚えるよりはずっとかんたんです。
なので、
「PHPはかんたん、PHPしか使えないプログラマーはバカ」
などと言ってる人はPHPを使ったことがないんじゃないかと思います。使ってみれば、言語として持っている機能はほとんど一緒だということが分かりますからね。
PHPには、標準関数の引数の並び方のポリシーがバラバラだったりするイライラがありますが、それは言語設計の美しさの問題であり、言語の習得難易度とは別の問題です。
そんなわけでメジャーな言語のほとんどは難易度C(ふつうに使える)なので、そんなに構えず、気になった言語を学んでみるのがいいと思います!