Dart始めました
超久しぶりになりました。
仕事が忙しかったり、家庭がバタバタしていたり、サーバが攻撃されたりとバタバタとしていましたが、最近は少し落ち着いてきまして、やっとこさいろいろしています。
そんなこんなで、ネットニュースを見ているとDartが2.6でシングルバイナリを出力できるようになった、なんてニュースを見まして。
.net coreのシングルバイナリに落胆していて、かつGoのシングルバイナリに惹かれるものとして、興味津々で食指を伸ばしてみました。
総論としては「割とバランス良いなこの言語」でした。
もともと僕は結構雑食で、いろんな言語をやってきましたが、バランスが良いものは久しぶりでしたね。
過去の遍歴とか印象は下記のような感じになっています。
ブラウザJSアプリ
一番好きなのですが、いかんせんファイルアクセスが出来ない。
ガワネイティブにせざるを得ない。ただ、それで十分なことは往々にある。
ただ、会社ではIE縛りのため、悲しいスクリプト書いてます。
サーバサイドにどんなデータも預かりたくないときが一番こまりますね。
node
割と好きなのですが、いざ使うとなるとnode_modulesが太ることが嫌でした。
クライアントに配るときに、nodeを入れてもらうのも大変だし、インターネットにつながっていない端末なんてのも居てnpm iが難しい。
個人的にもデプロイを自動化しているのですが、結局npm iをたたくようなコマンドになってしまう。
C#
Windowsでは最強。ただ、ソリューションを用意して、書いて、どうの、ってのをVisual Studioで行うのが面倒。
Linuxではmonoが必要でこれはまた大層な話になるし、ファイルが多い。(.net coreだと少しは楽ですが)。
.net coreだと、ソリューションを用意とかはコマンドでいけるようになったものの、やっぱりファイルが多いし、そもそも巨大。
社内Windows環境には.net core入ってないので、SCDしか作れないのですが、あまりの大きさに疑問を抱かれるので、なかなか小物ツールでは使えません。
ただ、一番社内で使って嫌な顔をされないのはC#です。
cpp
いろんな意味で最強ですが最弱。
さすがにWebサーバ書くのは苦行。かといってCGIにするのも今時どうかと思うし、何より自分の足を打ち抜く危険性が充分に高い。
PHP
実はサーバサイドでは相当なちょうど良い感?
実際に仕事でも使ってます。
CLIで使うのも、そんなに面倒ではないというか、実は書いてみると意外と便利だったりします。
でもWebサイトは構築めんどくさいしすぐ脆弱になる。
CLIは、別の人にクライアントサイドで動かしてもらうのは本当に大変。
Go
書き味が良い、思想は好き。
サーバサイドで使っても便利だし、CLIツールで使っても良い。
バイナリサイズは確かに小さくはないけど、大きい!って程でもない。何よりシングルバイナリ。
そんなこんな
そんなこんなで、Goをよく使っていましたが、最近はC#に戻ってました。.net coreが頑張りそうだったから……。
Goが良いのは、挙げたように本当にシングルバイナリなところ、クロスプラットフォームなところ、ネイティブで早いところ、Channelが使いやすいところです。言語的な割り切りが嫌いではないと言う部分も大いにありますね。errはすべてチェックすべし、例外は使うな、というのは、実は一部業界では特に変な話ではなかったりします。例外を出すならばプロセスが死すべきみたいな。まぁこの辺は何を大事にするかの問題ですしね。
Interfaceが自動的に実装した事になるなんてのはすごく書いてて気持ちが良い仕様ですが、逆にジェネリクスが無いのでアサーションだらけになったり、こう痒いところに手が届かない思いをすることもしばしば。
ただデプロイは本当に簡単。サーバならバイナリをポンで再起動。PHPのファイルをポンには少し負けますが。
クライアントだと、本当に簡単で、何もしてもらう必要も無く、実行形式1ファイルだけでOK。
バイナリの作成も簡単。ファイルを書いてgo build。
このあたりの手軽さは他の言語には無い手軽さです。
とにかく横着できる事が正義だと思ってるので、Dart2.6のシングルバイナリはとても魅力的に思えます。
しかもただのバンドルじゃなくてAOTかかってるとか凄い。.net coreはバンドルな上、どこかに展開されるし、そこからR2Rで起動してもやっぱりそれなりに遅い。
静的型付け言語らしくtree shakingがかなり効いてるっぽいのもあって、シングルバイナリの割に小さいバイナリができます。内部的にはaotランタイム+aotイメージという形になるのですが、Httpサーバあたりを実装すると、Goよりも少し小さいぐらいのサイズに。
ただ、静的リンクでは無いので、コンテナに乗せる時には少し面倒な感じになりそうです。
あと、起動時間は圧倒的に早くなりますが、実行時間は少し負ける事があります。JITだとアグレッシブな最適化が出来る(いざとなったらFallbackできる)のに対して、AOTだとそこまで詰められずに些か保守的になってしまうのは仕方ないです。そのため、.net coreのR2Rでは、起動時のAOTコンパイルイメージと、元のアセンブリを持つという方法で解決しています。
この点、速さは正義という観点から言うと一歩負けるのですが、一方、フルAOTを行ってJITを行わない、という方法は、圧倒的にメモリの使用量が下がります。このあたり、良いバランスを突いていると思います。
惜しむらくは、ホストと同じ実行形式しか出せない(aotイメージが作れないっぽい)って所ですが、まあ目をつぶりましょう。
確かに今時ではないですが、実行環境と同じ環境が用意できなければ、VMで動かすという手もあります。
言語としても凄く整理されている印象です。
強い型推論のある静的型付け言語。
async awaitが自然に書ける。
完全なオブジェクト指向であるが、トップレベルでの宣言も可能。
シングルスレッド型だけど、別スレッドは資源を共有しない形で立ち上げることができる(チャンネル並みとはいかないものの、Workerとしては充分)
メソッドの引数に名前付き引数が使える
ゲッター、セッターも普通に使える。
標準ライブラリが割といい感じでhttpクライアントやhttpサーバすら簡単に立てられる。
一時期はBetterJavaだと言われていたみたいですが、もはやそういう域は超えています。
C#、JavaScript、Kotlin、いろんな言語をごった煮にした感じの雰囲気ですね。
ちょっと感銘を受けすぎて、しばらくはこの言語使ってみて、スラスラかけるようになってから色々もっと評価したいところです。
惜しいのがパッケージ関係。リポジトリ的なのがあるのですが、ぶっちゃけ貧弱です。
ただ、Flutterも流行り始めたところですし、2.6でネイティブが書き出せるようになって、僕みたいな人が増えるとすると、これからもっとピュアDartなライブラリが発展することはまああり得ると思うので、滅茶苦茶注目です。
今ならライブラリ作り放題と言うのもありますしね。
しばらくはこれを使ってみようと思います。
と書いているうちにDart 2.7がリリースされました。
追いかけます(笑)