モダンな言語で書きたいというよりは、面倒くさい言語で書きたくないというか*1。
C++は標準出力の時点で気持ち悪いし、無限に覚えることがあるのでちょっと受け付けなかったり。あとは、その機能盛り盛りの影響でコンパイラ実装がクソ怠いという問題もあるらしく、とてもじゃないけど処理系を自分で一から手を付けたいとは思えないんですよね。
まあ例えばCで型だけ違う関数を複数定義するのは馬鹿みたいとか、たしかにそうなんだけど、それを解決するためだけにC++を使いたくないっていうか、もうちょっとモダンな言語で書きたい欲が。
計算科学を考えるとFortranって実はそんなに機能的には悪くないらしくて、今ではオブジェクト指向も取り入れてクラスもあるらしいんだけど、とはいえコードの見た目的にもうちょっと構造化してほしいなぁとか。Fortranはコード見るだけで実際に書いたことがほぼ無いけど。
Pythonはあの書き方が永遠に慣れないのでもう仲良くする気が湧かなくて…w
なんかPythonはJavaよりも新しい言語です、みたいな話がググるとわりと出てくるんだけど、この間違いを見るとアイデンティティ田島が憑依するからやめて欲しい。
これは私個人の趣向だと思ってるけど、C likeな言語しか受け付けないんだと思うんですよね。JavaScriptは好きなので。
Rustはちゃんと書いたことが無いので百聞しか知らないんですが、Golangはスッキリしてて結構好きなので、Goあたりで書けると色々と楽なんじゃないかなとずっと思ってたり。C開発に関わったカーニハンやトンプソンが関わっていて、C++嫌いな人たちが作った言語なので、Cが書ければ絶対にGoも書けるという設計になってます。
GoはCとかFortranよりは遅いんだけど*2、PythonでいいならGoでも良いじゃんと思うですが。
Pythonの何がダメかって言ったら、あの慣れない感じ以外だと根本的には遅いことなんだけど、ユースケースを踏まえるとライブラリで呼び出せる典型的な処理しか速く実行できないというところなんだろうなと。
あと、ステンシル計算のコードを愚直なCとライブラリ呼び出しだけで書いたPythonとで比較して思ったんだけど、ああいうのは関数化するとかえって何やってるのか分かりにくくなるんですよね。可読性が下がっちゃう(結果として保守性も)。
あらゆることをライブラリにしてしまうのは実際の計算科学アプリでは現実的ではないというのもあって、色々とそういうAPIは出ているものの、結局そんなに流行らずに愚直に書くのが主流になっているのが現状かなと思ってます。
でもGoだったらある程度ベタ書きでもそこそこ速いんだから、少なくともPythonよりは良い気がするんですよね。
新しい言語は流行らないと言うけど、それは結局過去の遺産を引き継げないからであって、過去の遺産を引き継げるようにすれば結構移行してくれるのでは?という気がPythonとか見てて思ってます。
もちろんそれだけではダメで、なんかキラーアプリがあるか、高速なハードウェアがあったときにそのハードを簡単に使うにはこの言語がベスト、とかのメリットが必要だと思うけど。
Pythonはちゃんとライブラリを整備して、機械学習がキラーアプリになったので流行ったと見えるので、他の言語についてもちゃんと既存のライブラリ(HPCならFortranライブラリ?)を使えるようにすれば結構移行してもらえるんじゃないかな?という気がするんですけどね。
RustもGoもCのライブラリを呼び出すのは比較的に簡単にできて(間接的にFortranのライブラリ呼び出しも可能で)、どちらもMPIに対応済みのようなので、HPCで使うことはわりとできる気がするんですよね。
RustはCとかC++と互換で同じレベルのこと(低レベル記述)が書けるらしく、使ってる人からの評判はめちゃくちゃ良いので、もう細かい記述をするときはC++とかじゃなくてRustを使う、という方向性のほうが色々と良いのでは?とか思ったり(少なくともC++よりはマシなんじゃないかなと。しらんけど)。
なんにしろ、計算科学に関してモダンな言語に移行するには、GoとかRustでライブラリが充実してくれることが第一歩かな?という感じ。
基本的なことや細かいことに関しては、Goはパッケージが結構あって高機能だし、使うときも至って簡単なので、スッキリしている割には簡単にできることは多い印象。よって、生産性が高いのでサーバーサイドではかなり重宝されているように見えます。
あとは、HPCなら、CPUではどうせそんなに重い処理をしないと割り切るなら、Goにしちゃっても良いんじゃないの?とかも思ってたり。Goが遅いのはコンパイラが最適化を頑張らないからだという説があるんですが、アクセラレータは別途なんかOpenACCとかで必要なことを補足して、デバイス側のコンパイルに関しては専用の最適化してくれるコンパイラ使えばそんなに悪くないんじゃないかなとか。
これは何を想定しているかと言えば、計算科学やってる人がFortranから移行する場合を考えていて、GoはFortranと比べても多分楽だし極めてモダンなので*3、GoからFortranの資産を使えるようにちゃんと整備してあげるとかすれば結構良いんじゃないかなという感じ。
とにかく、Fotranからの生産性の改善をしつつ、コンパイル言語でそこそこの性能の維持を考えるなら、Goは結構有力な選択肢の一つだと思うし、ライブラリ整備とアクセラレータ対応をちゃんとすれば結構状況を変えられるんじゃないかな?という考えをここに書いておこうかなと思ったという。
個人的にはGo推しなのでそうなって欲しいというのもありますが。
*1:ただの怠惰といえばそう思わないでもないけど、必要性のないことをいちいちしなきゃいけないとか無駄な作業が多いと萎えるんですよね。でも、それをどう解決するか考えるのがエンジニアリングだと思うので、なんかただ怠けてるだけだとか言われるとそれこそ敗北者じゃけぇ…とか未来の原始人とか色々と言いたく(ry
*2:古い言語が速いのはいろんなこと(ガベコレとか)を自動でやらずにマニュアルで指示するからだという話をよく見かけるんだけど、厳密にはそうではないと思っていて、コンパイラが最適化しやすければ速くなるし、そうじゃないと遅くなるという話だと思う。Fortranは最初にできた高級言語なので冗長だけど単純な構文であり、コンパイラに親和性がある(言ってしまえばコンパイラ実装が簡単な仕様になっている)ので、コンパイラがどういうコードを吐くかが一意に決定しやすいとかがあって、適当に書いても速くなるっていうのはおそらくそこらへんなんじゃないかなと思ってます。Cはもうちょっと冗長性を廃しているし、高機能になっているので、書くのは楽にはなるけどコードの解釈が複数発生する場合があって、そうするとコンパイラ実装のハードルは上がるし、おまけに通常のモードだと保守的な(確実に結果が正しくなるような)コード生成しかしなくなるので遅くなるという話。それと同じことがもっと抽象化されたスクリプト言語だとより言えて、それが結果として最適化を妨げている原因のはず。そして最適化しやすいかどうかは言語仕様というかコード上で表現されるコンパイルヒントの量にもよるけど、ハードにも依存する話。
*3:従来のクラス型オブジェクト指向から一周回って機能を削ぎ落とした形になっている。私は正直JavaScriptのプロトタイプベースでも悪くないと思ったし、Javaみたいにガチガチなクラスベースが正解ではないと思う。というか、Javaの高度にクラス化されたスパゲッティコードは関係性が分かりにくくて普通に辛かった。あとは、Goはうまいこと型が確実なところだけ型宣言を省略できるようになっている。私は、型は保守性のために通常は書くべきだと思ってるし、コンパイラ実装のことを考えると余計に無闇矢鱈な動的型付けはダメだと思ってる。なのでGoの設計はいろんな側面から見ても結構理想的という印象。