算譜王におれはなる!!!!

偏りはあると思うけど情報技術全般についてマイペースに書くよ。

俺とKotlinの馴れ初めと歩み 〜正式リリースに向けて〜 #ktac2015

f:id:ngsw_taro:20121129063626j:plain

12月になりました。2015年も残すところ1ヶ月ですね。 ということでKotlin Advent Calendar 2015の第1日目の記事です٩( 'ω' )و

年内にKotlin 1.0がリリースされるとの噂ですが、現バージョンは1.0-Beta2で、正式版リリースの足音が聞こえてきました。 正式版のリリースは、Kotlinユーザが待ちに待った瞬間です。 もちろん私もその一人です。 特にKotlinエバンジェリストを自称し、以前から活動していたこともあってその感動はひとしおでしょう。 本エントリではKotlinの思い出を時系列で綴っていきたいと思います。

そうそう、正式版がリリースされたときにはちょっとした誕生パーティーを開催する予定です。 と言っても内容はビアバッシュなLT大会です。 そこでも似たような話をすると思います。

Kotlinの登場と出会い

Kotlinはロシアの島の名前ですが、それがプログラミング言語(とその開発プロジェクト)の名前となって発表されたのは今から4年前の2011年、7月のことでした。 カリフォルニアで開かれたJVM Language Summitの中で、IntelliJ IDEAなどのIDEでおなじみのJetBrains社により発表されたのです。 当時の動画は先のリンクから、スライドは公式ブログ記事から見れます。

私はこのイベントも、JetBrainsの動向もチェックしていなかったのでKotlinと出会ったのはもう少し後でした。 最初にKotlinを知ったのはたぶんこの記事。 第一印象は「また新しい言語か...」と「かわいい名前だ」「素直な文法だなー」「静的型付けだ!」「JVM言語だ、試しやすい」でした。

で、いつもの私でしたらざっとサンプルコード眺めて〜ちょこっと動かしてみて〜終了!という感じだと思うのですが、今回は違いました。 言語として面白そうでゴール・設計思想に共感できたこと、登場して間もないこと、日本語情報がほぼ皆無であったこと、まわりにやっていそうな人がいなかったことなどいろいろあって「よし!Kotlin極めるか!」と思い立ったのでした。

Kotlinコンパイラのリリース

私がKotlinと出会った当初、言語の機能や文法を説明する簡単なドキュメントはありましたがコンパイラや動作環境がありませんでした。 やはり動かせないと楽しくありませんが、ひたすらドキュメントを読んでいました。 2012年2月中旬にKotlinコンパイラと、Webブラウザ上で動作する当時Web Demoと呼ばれる環境(今のtry.kotlinlang.orgみたいなやつ)がリリースされました。

ここで少し昔のKotlinの文法・機能について紹介します。 今の姿と大きく変わってはいませんが、小さい変更はたくさんあります。 例えばラムダ式やwhen式の->は、初期は=>でした。 それから、かつてはタプルがありました。

// タプル型とタプルリテラル
val pair: #(String, Int) = #("foo", 123)

pair._1 //=> "foo"

そのほか、関数型の記法がfun (A): Bから(A) -> Bに変わったりしました。

コントリビュート: エバンジェリストへの第一歩

2012年春頃、Kotlinについていろいろ調べてはブログに書く、というのを繰り返していました。 私の記念すべきKotlinプレゼン第1回目はTwitter API勉強会でした(お粗末ながらスライドはこちら)。

この頃、Kotlin標準ライブラリへのコミットもしました。 確かStringだったかな、の拡張関数をめちゃくちゃ作ってプルリク送ったら取り込まれました*1当時の公式ドキュメントブログでTaro Nagasawaと名前を載せていただけました。

〜M5: 洗練されていくKotlin

Kotlinは、マイルストーンという形で開発中のスナップショットを、数ヶ月のスパンでリリースされて来ました。 それぞれのマイルストーンでは、機能の追加・廃止、文法の変更、パフォーマンス改善やバグ修正などが含まれ、慎重かつ大胆にKotlinは成長を遂げて来ました。 新しいマイルストーンが公開されるたびにワクワクしながらリリースノートを読んでいたものです。

M1のような初期の頃は未実装の機能が追加されて行きました。 例えばローカル関数であったり列挙型、アノテーションなどが実装されました。

M2でKotlinのAndroidサポートが発表されました。 それから、invokeメソッドです。このメソッドを持ったオブジェクトへの参照、例えばfooとすると、foo.invoke()の代わりにfoo()と記述して呼び出せるようになりました。

M3では大きな変更がいくつかありました。 タプルが廃止されました。代わりにデータクラスと多重代入が導入されました。 ローカルに(つまり関数内に)classobjectを定義できるようになりました。 コレクションAPIが改善されました(ミュータブルとイミュータブルを区別するなど)。 セカンダリコンストラクタが廃止されました(たぶんこのバージョンのとき)。 そして、sureメソッドが廃止されました。これは!!と同じ操作を行うメソッドでした。

// タプルがなくなってもデータクラスで代用できる
val pair: Pair<String, Int> = "hoge" to 123
val (str, n) = pair
str //=> "hoge"

少し脇道に逸れると、この時期に野心的なWebフレームワークが登場しました。 名前をKaraと言い、HTMLやCSSまでもKotlin内部DSLで型安全に書こうとするMVCフレームワークです。 すごく面白いフレームワークでしたが、あまりプロジェクト進捗がアクティブでなかったので流行はしていないと思います。

M4ではデータクラスにcopyメソッドが追加されイミュータブルスタイルの変更が容易になりました。 あと、この時期ですね、KAnnotatorが出たのは。これは既存のJavaコードにNotNull/Nullableの外部アノテーションを自動付加するツールです。

エバンジェリスト的な活動としては、この時期あたりに日経ソフトウエアに単発記事を寄稿させていただきました。

M5.x。マイルストーンなのに刻んで来るのか〜とちょっと驚きました。 内部クラス、コンストラクタ引数のデフォルト値、レンジの改良、関数のパラメータ変数の変更不可、関数参照などがサポートされました。 また、M5.2ではSAM(Single Abstract Method)変換の第一歩が実装されました。M5.3ではより使い勝手が良くなっています。

// M5.2
button.setOnClickListener(View.OnClickListener { ... })

// M5.3
button.setOnClickListener { ... }

それから大きなところとしてはDelegated Propertyが実装されました。 これはユニークな機能ですね。プロパティの遅延初期化、観測など言語組み込みではなくAPIとして実装できることを意味します。

この頃に日本Kotlinユーザグループを発足、日本初のKotlin勉強会を開催しました。

〜M11: Androidを意識し成長を続ける

M6.x。SAM変換の改善、Java 8対応。 アノテーション改良やJava相互運用性の向上(static field)、ラムダ式から外側の関数のreturn、TCO(Tail Call Optimization)のサポートなど。

M7では、発表当初から仕様に盛り込まれていたインライン関数がついに実装されました。 高階関数ラムダ式を渡す時に、オブジェクト化せずインライン展開することでコストを軽減するための機能です。 また、例外のチェック義務がないKotlinコードをJavaから使い扱いやすくするためにthrowsアノテーションが導入されました。

ここあたりで第1回関西Kotlin勉強会がありました。

M8ではちょっとした変更。 M9ではM3でサポートされたローカルobjectが廃止されました。 さらにplatformStaticplatformNameといったアノテーションでさらにJavaに歩み寄る仕組みが提供されました(それぞれ今ではJvmStaticJvmNameにリネーム)。 あとPlatform Typeと呼ばれる、JavaコードをKotlinで見た時のNotNull/Nullable関係のやつ。

Kotlin用AndroidビューバインディングライブラリのKotterKnifeが公開されたのはこのあたりです。

M10ではReified Type Parameterが実装されました。 これはジェネリック関数で型パラメータの型情報を実行時に参照できる機能です。

この時期、2015年春にSoftware DesignでKotlin入門の連載がスタートしました。 第1回 DroidKaigiでKotlinについて発表しました。 Kotlinの名前がそこそこ知れて、たまにバズる記事が登場するようになったのもこの時期の前後です。

M11では、M3で廃止されたセカンダリコンストラクタをより洗練させたものを導入しまた一歩Javaに歩み寄りました。 ほかには、イニシャライザにinitキーワード必須、companion objectラムダ式のもう一つの記法などの変更が入りました。

Kotlin内部DSLAndroidにおけるレイアウトを構築するAnkoというライブラリが発表されました。 また、KotlinでAnnotation Processingを行うkaptと呼ばれるツールがリリースされました。

〜Beta2: Javaとの相互運用性100%への挑戦

当初よりJavaとの相互運用性100%を謳っていましたが、実際には細かいところでうまく連携できないなどの問題がありました。 これまでもJavaとKotlinが仲良くするための仕組みが導入されて来ましたが、この頃からより一層Javaを意識するようになったと思います。

M12には、アノテーションの記法の変更、それに伴うラベルの記法の変更、traitからinterfaceへのリネーム、列挙型の文法変更などが含まれます。 インタフェースのクラス継承が非推奨になり(これはちょっとショック)、class objectは廃止されました。

M12から3ヶ月以上空いてM13がリリースされました。 プロパティの初期化をあとで行うことを明示するためのアノテーションlateinitが導入され、DIフレームワークとの相性が良くなりました。 直和型を表現するためにSealed Classがサポートされました。 そのほか細かい変更と、Javaとの相互運用性を高める変更がいくつか入りました。

日本語でKotlinについて話せるSlackをつくりました。

M14ではoperatorconstなどのキーワードが追加されました。 これもJavaと仲良くする工夫です。

そして今年10月に1.0-Beta候補版が、その2週間後に1.0-Betaがリリースされました! infixキーワードを導入するなど、Javaとの親和性をさらに高める変更が入りました。 11月16日には1.0-Beta2がリリースされ、小さな変更が入りました。

そして1.0へ

もうすぐ1.0がリリースされる...はずです。 3年半以上Kotlinの成長を見てきた分、途中で頓挫するプロジェクトも少なくない中、正式リリースにこぎ着けるのは本当に嬉しいです。

Kotlinユーザも増えてきました。 エンジニアの求人ページに「使用言語: Kotlin」と記載している企業もちょっとずつ増えてきました(すごい!)。 今年のKotlinアドベントカレンダーはすぐに満員になりました!

とはいえ、未実装の機能があるのが気掛かりです。 例えば型エイリアス(あれ、これ結局やめたんだっけ?)など。 ともかく1.0のリリースは楽しみです。これをきっかけに導入する企業が増えたらいいなぁ。

JetBrains公認エバンジェリストになること。 一応今は私が勝手にやってる活動なので「自称」を必ず付けて誤解を回避しています。 金銭的な報酬はいらないので、公式に認めて欲しいです(地方遠征の旅費などの経費はもらいたいけども...)。

もう1つの夢は、Kotlinが巨大プロジェクトで採用されること。 KotlinはJavaよりも型安全だし、NULL安全です。 文法もシンプルでやりたいことを素直に書き下せ、熟練度の差によるコードのばらつきが抑えられ大人数のプロジェクトに向いていると思います(ただの主観)。 エンジニアのQOLの向上につながれば、エバンジェリスト冥利に尽きます。

おわりに

という感じのだらだらしたエントリで始まったKotlin Advent Calendar 2015なわけですが、明日以降の盛り上がりに期待ですね!! 明日は@takuji31さんdelegate関係について書いていただけるようです! それでは、ありがとうございました。

*1:再構成や改善が進み、今やそのコードは残っていません。。