「Java捨ててC#にでも振ったほうがいいのかなあ」
なんて聞かれ、
「nodeとかあるしJSのがまだマシじゃないすかね、というかOracleから逃げた結果がMS行きってどうなんすか」
とか答えたあと、もう少し考えてみたほうが良さそうだなあ、と思ったので考えてみる。
なお、筆者は諸事情でこれまでJava仕事が多かった人種ではあるものの、基本的にJava嫌いかつOracle嫌い1であるため、考察には強いバイアスが掛かっている可能性が高いことを申し添える。
TL; DR
- 「Javaは捨てたほうがいいんじゃないのか」という発想は間違っていないが、性急、または手遅れである。
- そもそも特定言語一本で行くような無茶をしてはならない。また今回みたいなことになりたいんでなければ。
Javaの強み
「Javaの強みはなんですか?」
たぶん、Javaの草創期は「オブジェクト指向」が上がったのではなかろうか。
というのもマシンスペックの問題で、相対的にJVMの負担が重かった。ランタイムを使う言語は「ランタイム自体が重い」という問題を乗り越えねばならないが、JVMは特に辛かったのだ。
今は亡きSun Microsystemsの言う"Write once, run anywhere"など、当時"遅いけど許して"という言い訳にしか聞こえなかったものである。
では、今この問に答えるとどうなるか。
考えるまでもない。"Write once, run anywhere"。間違いなくこれだろう。もっと厳密に言えば、これを成立させる"Java VMというインフラ"そのものだ。
半導体技術の進歩に伴うコンピュータのスペックアップは、今やJVMごときの負担などものともしなくなった。
Javaは今や、言ってみればDockerのような、VMコンテナとそれに拠って成立するインフラ機構の一種である。
如何なるコードも、それがJavaである限り、Java VMで動作する。
Java VMは、どこ向けのマシンにも供給される。それも、タダで。
だから、Javaはどこでも動く。"Write once, run anywhere"。
詳しく調べていないので正確でないかもしれないが、OracleがGoogleと殴り合いを演じたのもこのあたりが原因だろう。
Apache Hermonyから始まった一連のJava VM周りのゴタゴタによるものとはいえ、VMの供給をどこかに"乗っ取られる"とか、そうでなくとも単一VMな状況が破壊され"やりづらくなる"のは致命的な問題だったのだから。
なぜ致命的か。
Javaには今や、VM (と現存する資産) 以外の強みがないからだ。
……今日日、オブジェクト指向言語はありふれてるからね。仕方ないね。
Javaの弱み
Javaはその構造上、Java VMが必須である。
Java VMとそこらのランタイムが違うところは、"VM"と名乗る程度には分離されており、しかも読むものはJavaバイトコード、つまりJVM用の機械語であるところだろう。
この方式は
- バイトコードではあるのでインタプリタよりはいくらか速い
- Java VMをターゲットとしてビルドするため、理論上2環境差による動作不良が起こらず、手軽である
という利点がある一方で、
- Java VMを動作させた上でアプリケーションを走らせねばならず、マシンパワーをより多く要求する
- Java VMを各環境に合わせて構築しなければならず、供給側の負担が大きい
- 一旦バイトコードとしてコンパイルさせてしまうため、後方互換を保つならJava VM側の仕様変更が難しい3
という欠点を併せ持つ。
欠点のうち、マシンパワーの問題は時間が解決した。マシンパワーそのものが強化された上、VMは進歩し、コードの最適化も強力になった。
もちろんインタプリタを利用する言語もこれは同じことだが、速度的にはまだ負けていない。
C/C++のような"本当に速い"言語に比べると軽トラvsジェット戦闘機といった具合だが、逆に手軽さでは勝っている。
ところで、SunにしろOracleにしろ、名前がやたら御大層ではあるが営利企業だ。
いったいこれでどうやって儲けるつもりなんだ?
Javaの強みはJava VMというインフラそのものである。
しかし、政権交代でインフラ費削った直後に大震災が来たどっかの島国の住民ならよくわかっていることだろう。インフラの整備ほど金が掛かるものはない。
Javaなんてものは、どう考えてもバカでかい負債なのだ――Oracleにとって。
だからこその方針転換であり、いわゆる"有料化"だ。
誰もが走る道路、誰もが吸う空気、これを有料にすればどうあがいても儲かるのは目に見えている。
これはそこまで浸透させた側が悪いのだ。相手も営利でやっているのだからこれをとやかくいうべきではないし、むしろそれが適正なら対価は払われるべきであろう。
つまりJava最大の弱みとは、Java VMというインフラへの依存そのものである。
Java最大の強みたる"どこでも使えるインフラ"Java VMは、Java VMへ、ひいてはOracleへの依存という最大の弱みである。
……というか、だからこそ今騒ぎになっているのだが。
実際のところ、Javaが有料化されるという事実は重い。「タダで、難しいこと考えなくても割と動くインフラが使える」という利点が失われるからだ。
しかしそもそもJavaの、特に標準APIの設計は古臭く、カビの生えたような代物である、というのはよく言われていたことだ4。
実際、Javaの言語仕様やその他特性は当時でこそ最新であったものの、現在においては無数のフォロワーに追い抜かれて久しい骨董品である。
Java 8/9/10/11とリファインが続き、不便だったり不毛だったりする部分が次々改善されているとはいえ、根本的な古さを捨てられないという問題のしわ寄せは様々に問題を引き起こし続けて久しい5。
我々はどうすべきか
Javaを完全に代替しうる言語は存在しない6。
いくらプログラミングが急速に進化していると言っても、
……これだけの条件を片端から満たす言語など、この世にはおそらく存在するまい。
当然のことかもしれない。Javaは、Java VMはそれだけ強かったのだ。
しかしもっと言えば、我々はそれだけOracleに依存させられていたのだ。
我々はいい加減、単一言語でほとんどなんでも対処できるという幻想を殺さねばならない。
Javaを捨てるか否か?そうではない。どの分野に注力し、あるいは注力しないため、どの分野にどの言語を考えるか、どの言語をどれだけやるか、である。
というわけで、"部分的に"Javaの代替になりそうな言語を挙げていこうと思う。
幸いなことに、Java (そしてそのある意味で前身たるC/C++と、祖先たるALGOL) が非常に強大だったおかげで、現在世の中で使われているものには転換が容易なものが多い。
C#9
この記事を書き始めた大本になったと言ってもいいかもしれない。Microsoft製。
もともとはVB.netあたりと同様C#.netと名乗っていた時期があり、実は.net界隈に限らずC#する気だったのだとも噂される10。
欠点は冒頭にも書いたとおり、Oracleから逃げてMSに捕まるということ、そしてXamarinを得てなお利用範囲が狭いことである。
結局の所、.netの本場はWindowsである。同じMS製品としてSharepointなどと相性が悪くないとも聞く。
しかし、困ったことにそもそもそれら"オプション"がひどく微妙で、高価で、無闇矢鱈と重厚長大なのだ。Sharepoint?Office?それで、問題一つ解決するのに一体いくらかかるのかね?
もし、JavaからC#に移行するというなら、理由は一つであろう――C#はJavaに近い。一説にはMS版Java、J#の血を引いているせいだとも言われるが、1つの巨大企業に命を預けるという意味でも同一である。
逆に言えば、そういった巨大企業に巻かれる形で行くつもりなら、選択肢としてはアリかもしれない。
Ruby
国産であることでも知られる、オブジェクト指向スクリプト言語。もともとシェルで利用することを前提とされており、実は組込み用実装さえ存在するなんでもアリ言語である。……が、Web向けとして知られているのは言うまでもない。
では何故Web向け言語として広まったか? これは間違いなく
RoRことRuby on Railsの流行によるものだろう。
Railsはその流儀と思考に沿う限りにおいて、凄まじい速さで開発ができる――というのが売りであった。当時のGoogleに"いいHackだ"として賞を受けたあたりで爆発的に流行し、世界中に広まった。
そしてその結果Railsコミュニティは急速に劣化した。
2008年の段階でZed Shawが"Rails is a ghetto"とこき下ろしたように、あるいは"RubyはMatzの発明品ではない、DHH11のオリジナルだ"というようないくらなんでもひどいジョークが出回っていた12ように、コミュニティそのものの質が死んだ。
これによりRails、そしてRubyから多くの人が離れた結果、一時とは言え世界を席捲した赤い宝石はあっという間に日本ローカルへ戻りつつある――というのは明らかに言いすぎだろうが、しかし、海外におけるRubyコミュニティ自体は弱体化しつつあるようだ13。
JavaからRubyへ行くとすれば、やはりWeb方面を重視した場合だろう。Web方面以外をやるためにRubyを選択する場合、その資料をどう探すかが問題になる可能性がある。そもそも「Rubyで非Webって何いってんだこいつ?」という反応をされる可能性もある。
もっとも、極めて限定的な一地方 (具体的には島根県) を拠点とするなら、場合によっては政治的に強力かもしれない14。
JavaScript
Netscape Communications、Brendan Eichの作。ネスケことNetscape Navigatorの機能として登場した、おそらく現代人にとって最も処理系15に触れる機会の多いスクリプト言語だろう。
ECMAによる標準化、Nodeによるサーバサイド進出を経て、ついに「ブラウザ用言語」から「汎用言語」にパワーアップした……といえるかもしれない存在である。
Nodeは現状非常に強力であり、モジュールも多様な物が揃っている。Web出身という身の上もあってWeb方面が本業な感は否めないものの、何もかもがWebに繋がりつつある今となってはむしろアドバンテージにすらなりうる。
また、登場以来活躍の場を広げ続けているマークアップ、JSONはもともとJavaScriptの記法であり、eval16するだけでデシリアライズできるほどである。
JavaからJavaScriptに行くとすれば、これはやはりWeb方面であろうが、それ以外でも利用されつつあるため、複数方面での展開が考えられる。DL用のライブラリを見かけた(ような気さえする)ぐらいだ。
特に重要なのはElectronの存在である。JavaScript製のクライアントサイド(あるいは単に「GUIアプリケーション」でくくったほうが良いやもしれない)といえば現状Electronであろう(特にPC向け)。
既にVSCodeやDiscordのような"大物"が存在することは、後押しにはなっても足を引っ張ることはあるまい。
しかし、JavaScriptは実行速度に大きな問題を抱えている。何をどう頑張ってもどっかで遅いのだ。
逆に言えば、なんらかの(例えばWebならサーバレスアーキテクチャのような)手段で速度問題を解消してやれば、銀の弾丸とまでは行かずとも鉛玉ぐらいには十分使いうるだろう。
まとめ
Q. Javaは捨てたほうがいいんじゃないのか?
A. 捨てたほうがいい。しかし、それは今に始まったことではないし、捨てるのもリスクが大きいことを覚悟すべきである。もっとも、クライアントが嫌がる可能性も考えるとトントンぐらいかもしれない。
Q. Javaの代わりに何を使えばいいのか?
A. Javaを完全に代替しうる言語は存在しないし、なんでもかんでも一つで済ませるのは困難極まりないし、今回のような事態を起こすのでハイリスクである。多数の言語を用途ごとに使い分けるべきだ。例えば、機械学習ならPythonを使うように。
Q. しかし、多方面を支え続けるのは難しい。
A. あえて考えるなら、C#やJavaScript、Rubyあたりが有力である。しかし、単一言語に集中したい理由が例えば教育コストであるなら、そもそもJavaを使い続けるほうが話が早い。特にJavaとC#あたりは差が小さいし、JavaScriptのような学習コストの低く文法の似た言語を使う手もある。
-
そういう宗教である。ご容赦願いたい。 ↩
-
現実がそうでないのはご存知の通りである。まあ、単一バイナリがどこでも起動する、というだけで十分脅威なのだが。 ↩
-
これがインタプリタなら解釈手順とかをうまくいじればまだ回避しやすいのだが、バイトコードまで落としてしまうとそうもいかないだろう。 ↩
-
大半は本当に古いんだから許してやれと思わんでもないが、実際使うと巫山戯るなと殴りたくなる。理不尽なものだ。 ↩
-
最たる例はGenerics、というかErasureであろう。あとはchar周りだろうか。 ↩
-
あったらとっくにそっちに乗り換えているし、それで仕事させてくれるところに行っている。 ↩
-
もっとも、最近のスクリプト言語は大抵JIT最適化をやっているので速度差はだいぶ縮まっているのだが。 ↩
-
誰も知らない言語を誰が使うんだ? ↩
-
どういうわけかエスケープが効かない…… ↩
-
現実がそうでないのは(ry もっともこれはMonoやXamarinなど、.netそのものの拡張によって間接的に実現しているし、そもそも単に他と揃えただけだろう。 ↩
-
David Heinemeier Hansson, 要するにRoRの作者。 ↩
-
時期不詳。 ↩
-
まあ、Railsという"災害"の前後で考えると、むしろ利益を得られている可能性すらある。これでよかったのかもしれない。 ↩
-
Matzは鳥取出身だが島根県松江市在住であり、名誉市民号を受けていたりする。確かここらへんの都合で支援もやっていたと思うが、今もやっているんだろうか。 ↩
-
現代のWebブラウザのこと。わざとそうしない限り、ブラウザ=JavaScriptの処理系であると言っても過言ではあるまい。 ↩
-
指定されたコードを評価、つまり実行する関数。アブナイのでちゃんとJSON読み書きするためのものが後に作られた。 ↩