Go にジェネリクスがなくても構わない人たちに対する批判について

なんども繰り返される話でうんざりなんだけど、繰り返されるたびに反論するのもアレなので、URL貼れるように記事にしておく。

頑なに要らないと言ってる人が具体的にどの発言のことを差してるのか分からないけど、コア開発者たちはツールチェインやランタイムの進化を優先していただけで頑なに拒否してたりはしません。今はツールチェインやランタイムが大分進化したから、Goの適用範囲を広げるためにジェネリクスを含めて機能追加も検討し始めようかっていうフェーズです。

あとどの言語にもちょっと公平的な見方ができなくなった痛いファンはいるもので、そういった人たちをいちいちあげつらってこういう言い方で失笑するのは、別に止めはしないけど自分の格を下げるだけだと思う。

逆に言語にこだわらない、Goの広い分野への布教に熱心でない人は、ジェネリクスが無いことが不便な場面ではわざわざGoを選ばないでC++C#JavaやRustなどを使ってるので、本当にジェネリクスが無いことで困ってない。そういった意味で「別にGoにはジェネリクス要らない」「ジェネリクスより先にXXX欲しい」人たちを失笑するのは、やはり笑ってる方がバカっぽい。RubyC++も使える人が「別にRubyに静的型要らない」って言ってるのに対して「こいつ静的型の便利さ理解してないよwww」と言ってるのと同じ。

Goは特に今で言うマイクロサービス的なものを(色んな意味で)効率よく開発するために作られた言語で、DBとかJSONとかRedisとか扱ってHTTP API提供する簡単なサービスを書いてみたら分かると思うんだけど、本当にジェネリクスがなくて不便な場面ってメチャクチャ少ない。 interface {} (Javaでいう object) が出て来る場面って、ジェネリクスが無いせいで出て来ることは本当に稀。

JSONRDB使っていてコードジェネレータを使わない場面では interface{} がたくさん出て来るけど、それはジェネリクス持ってる言語もジェネリクスじゃなくてリフレクションで解決しててGoと同じ不便さを持ってるだろう。

log.Printf("%v %v %v", a, b,c) みたいな場合、可変長引数が interface {} だけど、それもあんまりジェネリクス関係ないし、しかも静解析ツールがフォーマット文字列と引数の整合性チェックしてくれるのでやっぱり困ってる実感ない。

唯一面倒、あるいは不格好だなぁと思うのはソートだ。ジェネリックなソート関数を使うのが面倒で、便利さのために sort.Ints() とか sort.Strings() とかを提供している*1のが不格好なんだけど、この面倒臭さも単純にジェネリクスが無いせいとはいうわけでもない。

例えば Javaジェネリクスがプリミティブ型にそのまま対応したとしても、プリミティブ型が .compareTo() を持ってないし演算子オーバーロードとか「この演算子を定義している型」を宣言する方法を持ってないから、ジェネリック関数に渡すには「値の比較方法」「値の交換方法」を教えてあげないといけなくて面倒だよね。

今のGoのソートの面倒さはそれの方に近くて、比較方法と交換方法をいちいち教えないといけない部分が面倒くさい。もちろんC++のテンプレートみたいなのもあるわけで、Goに上手くフィットするジェネリクスならこの問題も解決するはずだ。

でも、Goがジェネリクス持ってないことを非難するときにはJavaを「持ってる」側に分類しておいて、Javaレベルのジェネリクスはあんまり嬉しくない*2ことを説明すると「ジェネリクスJavaだけの機能じゃない。Javaと比較すんな」みたいな反応されるのにはうんざり。

これは2割くらいしか同意できない。

昔にJavaジェネリクスが無いことを擁護していたユーザーは、きっとC++のテンプレートしか知らなくて、しかも当時のC++コンパイルエラーは読めたものじゃなかったのだろう。あのコンパイルエラーと戦うよりは、 int x = (int)vec.get(i) と書くほうが生産性が高く感じる人が多くても不思議ではない。

一方で今のGoユーザーは、 int v = (int)v.get(i) なんてコードはほぼ書かない。昔のJavaと違って、動的配列もマッピング型もジェネリックな組み込み型だから。たまに書く場合も、JSONmap[string]interface{} で扱うとか、どんな型でも値として入れられる Context から値を取り出すとか、ジェネリックがあっても便利になるとは思えないケースがほとんどだ。

なので、アプリ開発言語としてメジャーなのがC++Javaしか無かった当時のJavaユーザーと、そもそもジェネリクスがなくて困るケースにあまり遭遇しない、そういうケースは別にGo以外でも他のメジャーな言語使えばいい今のGoユーザーでは、「ジェネリクスいらない」の意味が全く異なる。どちらにしろ、両者とも「横目により良いものを見ながらやせ我慢」してたわけじゃないので「酸っぱいぶどう」というのは違うと思う。

逆に2割の同意できる部分としては、今ジェネリクス要らないと思ってるGoユーザーも、(Javaほどではないとはいえ)実際に追加されたら便利だと思うだろう。

さっきも書いたとおり、Goユーザーがジェネリクスが無い不便さを実感しにくいのは int v = (int)v.get(i) のような、ジェネリクスがあればダウンキャストが要らなくなるコードにほとんど遭遇しないからだ。

だけど、実際にはジェネリクスなしで型安全を手に入れるために、「イディオム」というコストを払っている。例えばFIFOキューから値を取り出すなら、今は v := q[0]; q = q[1:] なのが、ジェネリクスがあれば v, ok := q.Pop() になるだろう。後者に慣れたら、きっと前者は面倒に感じるはずだ。

なので、Goにジェネリクスを足す理由が適用範囲を広げるためだとしても、今Goがフィットしてる分野にもちゃんとメリットはあると思う。

*1:ちゃんと確認してないので、単に便利さのためだけじゃなくて最適化のために専用のアルゴリズムが使われているかもしれない

*2:いちいちboxingするコスト、Javaユーザーは許容するかもしれないけど、高性能サーバーを手早く書きたいGoユーザーは許容しないだろう

Heroku 上での Python 3 率

requestsなどの作者として有名な、HerokuのKenneth Reitzさんが、とてもうれしいグラフを公開してくれていたのでシェアさせていただきます

デフォルトが Python 3 になったらみんな Python 3 使うんだよね。

XPS13 モニター2 (Ubuntu導入編) #DELLアンバサダー

XPS13のQHD+モニターはグレア液晶で、FullHD液晶ならアンチグレア液晶です。 ノートPCを使うのがリビングでベランダを背にする位置が多く、明るい時間帯はかなり反射が眩しくなるのでアンチグレアの方が良かった。 Dellに限らず、2-in-1じゃないクラムシェルモデルはエンタメ性能よりもビジネス性能を重視してアンチグレアにして欲しいと思います。

バッテリーは Ubuntu でも大体10時間位持ちそうです。tlpをインストールしただけで特別なチューニングはしていませんが、1時間あたり10%ずつ減っていく感じです。 なお、BIOS設定画面にタッチパネルを無効化するオプションがあったのですが、体感できる差はありませんでした。 バッテリー時間が長いほうが良い人もFullHDモデルにしておいたほうが良さそうです。QHD+綺麗なんですけどね。。。

さて、Ubuntuデュアルブート化に挑戦したのですが、失敗しました。 Ubuntuは起動するのですが、Windows側を起動しようとしたらBitLockerの回復キーを求められ、記録してなかったのでWindowsを起動できません。 最近はセキュアブート+BitLockerとか、Intelの何かでBIOSSATAモードをAHCIにしないとNVMe SSDが使えなかったり、デュアルブート化するときの罠が多くて大変ですね。 回復ドライブからファクトリーリセットできるはずですが、面倒なのでモニター返却までこのままUbuntu1本で行きます。

Ubuntu 17.04 は最初に起動したときから自動で HiDPI を認識していたようで、2倍のスケーリングがかかっています。 期間限定のモニターであんまり設定に時間をつぎ込みたくないので、設定頑張らなくて良いのは便利。 私はデスクトップ環境にUnityを使っていますが、Gnomeも今のバージョンは整数スケールしか対応してないので、150%とかじゃなくて200%のスケールがちょうどいいQHD+は好都合だと思います。 (ubuntugnomeのHiDPIサポート改善に協力しているらしいので今後はまた変わってくると思いますが。)

一方、タッチパッドの使用感は良いものの、タイピング中の誤爆を結構してしまいます。 テーブルの上で使っているときは少し意識的に手首を浮かせていれば問題ないのですが、ソファで膝の上に置いたりすると結構な頻度で邪魔されます。 適当にググって見つけたPalm Detectionの設定は導入してみたのですが、うまく動いてないのかまだ誤爆はあります。

ACアダプタは、他のレビューでも叩かれていますが、AC側がミッキーコネクタな上にゴツいです。 あと、XPS 13はUSB PDでの給電にも対応しています。 試しに はんぺんさんの記事 で規格適合と紹介された PowerPort Speed 1 PD30 を試してみたところ、きちんと充電することができました。 30Wだと充電してくれないノートもあるらしいですが、XPS13は大丈夫だったので、モバイル時の荷物が減らせそうです。 ただ、このACアダプタはコンパクトな代わりにかなり熱くなって怖いので、普段は付属のACアダプタを使っています。

XPS 13 のモニターに当選しました #DELLアンバサダー

DELLアンバサダープログラムでXPS13のモニターに当選し、今日届きました。これから約1か月モニターしていきます。

モニターに応募した理由は、ちょうど今使っている ThinkPad X 250 の次のノートを物色していたからです。 XPS 13 以外の候補は、 X1 Carbon (14インチなのに1.13kgと軽い!), hp の Envy 13 (大きさ重さはほぼ同じだけど、12万円台でSSDが512GBにできる!), MateBook X (高いけど1kg台と軽くてモニターが3:2!)とどれも魅力的なので、XPS13も次のモデルではマイチェンじゃなくてもっとせめて欲しいところ。(あとできれば Ryzen mobile APUにしたい)

ちなみに、モニター終わったら貰える/安く買い取れるとかそういうのはないので、変に気を遣わずに X250 や会社で使っている MBP 13" (多分 2013 late) と比べて気になる点は厳しくガンガン書いてしまいます。

ThinkPad X250 と比べると、フットプリントはほぼ同じで、液晶が12.5インチから13.3インチに拡大しました。まだ日本語の読み書きしかしていないので、このサイズ差が生産性に影響するかは未知数です。 厚さも、X250のキーボード側の厚さがちょうど XPS13 の厚さくらいで、今どきの Macbook や ZenBook 3 みたいな感動的な薄さではないものの、十分スタイリッシュになりました。

液晶側は180度までは開きませんが、特別窮屈な感じはしません。カウンターキッチンの上において立ったまま使うときなどでも問題なく使えます。これが狭めのノートだとソファでくつろぎながら膝を立てたところにノートPCを載せて使う時とかに窮屈な感じになってしまうのですが、XPS13は及第点です。

f:id:methane:20170722170704j:plain

液晶は3200x1800のタッチパネルで奇麗です。Windowsで推奨のスケールは250%になってますが、200%にするとちょうどいい感じだし、フルHDの場合に使う125%や150%によくあるボケやレイアウトずれ(文字のはみだし)なんかも200%なら軽減されるんじゃないかなという淡い期待もあります。

一方で、重さはFull HDモデルが1.2kgなのに対してQHD+モデルは1.29kgらしく、スケールメーターを持ってないので計測はできませんが、持った感じはズシリと感じます。X250は1.44kgあるのでまだそれよりは軽いんですけどね。タッチなしのQHD+出ないかなぁ。タッチ欲しい人は2in1買うでしょ。今どきあえてクラムシェル選ぶ人にはタッチ要らないでしょ。(偏見)

その他のスペックはi7/8GB/256GBです。DellオンラインストアではQHD+は16G/512Gのモデルでしか選べないので簡単に入手できるスペックとは違うみたいです。個人的にはCPUがi5で良いので16GB/512GB/QHD+タッチなしが15万以下で選べるようになってほしいところ。 色はピンクゴールドだけど、落ち着いた色で男が使っても違和感無いです。

f:id:methane:20170722171608j:plain

気になるのが、ときどきキーボードの左側(Sキーあたり)からキュルキュル音が鳴ります。なるタイミングはよくわからない。 調べるとコイル鳴き症状があるようでたぶんそれだと思います。

キーボードのストロークは2013年のMBPと同じくらいで、感じはMBPがカシャカシャなのに対してちょっとゴムっぽいクリック感になります。ゴムっぽいといってもグニョっとネバ付く感じはなくて別に悪くないです。キーボードは右側が細くなってますが X250 も同じなので特に問題には感じてません。音もMBPより静かになったと思います。

ただ、エンターキーの右側を押すとキーが水平に下がるのではなく右側が下がる感じになるので、それが気になる。キーボードの右側の少し高くなってる面に小指が当たってしまいます。 MacBook, ZenBook 3, MateBook X みたいに本体の左右ギリギリまでキーボードが広がっている必要はありませんが、それでももう少しだけ余裕が欲しかった。 それ以外の配置はとてもよく、特にスペースキーはホームポジションで両手の親指がちょうどスペースキーの左右に乗せられるのが好印象です。

f:id:methane:20170723010211j:plain

ファンの音はMBP13と同じくらいですが、Chromeでこの記事を書いてる間もずっと回っていて、MBP13よりも回り始めやすい印象。あと、回ってるときに本体を傾けたり、液晶を閉じて持つと、ファンがどこかに干渉してハチが飛ぶ音みたいな音が鳴ります。ファンが壊れそうで耐久性が不安になるのでこれは改善してほしい。

モニタープログラムの決まりで改造は禁止なのですが、質問したところ返却前にリカバリするならデュアルブート化してUbuntuをインストールするのは問題ないそうです。 が、Windowsのディスク管理からパーティションの縮小ができなかったので、とりあえずWindows 10 CU にアップデートして使っています。

go-sql-driver/mysql の v1.3 が出たよ

リリース日が去年の12月なんでもう時間経っちゃってるんだけど、一応日本語でアナウンスしておきます。

MySQLドライバの go-sql-driver/mysql が、 Go 1.8 の新機能サポートの前に安定版リリースしようということで、 v1.3 のタグが打たれました。

master ブランチに昨日 (2017-03-23) から 大きい変更 をマージし始めたんで、glide などの依存管理ツールを使ってる人は、プロダクション/ステージングでは v1.3 に固定しておくことをお勧めします。 (それ以外の人はむしろ master ブランチでテストしてくれると嬉しい。)

このブログに乗せているコードは引用を除き CC0 1.0 で提供します。