Kotlin Fest2019に参加しました<<後編>>

残暑お見舞い申し上げます。

まだまだ暑い日が続きますが、次回の基本情報技術者試験まで1ヶ月強となりました。
午後の練習問題は相変わらず6割超えないくらいに終わってます…。


さて、転職したばかりの環境でヒィヒィ言っているうちにとうとう9月の中旬になってしまいました。増税前に会社の金で行ったKotlinFest後編についてまとめていこうと思います。


八木俊広さん ( @sys1yagi )
Kotlin コルーチンを 理解しよう 2019


小谷野 雄史さん ( @bandwagondagon )
Coroutinesから紐解くKtorの仕組み


Malvin Sutantoさん ( @MalvinSutanto )
Code Generation in Kotlin with Annotation and KotlinPoet


木原 快さん ( @gumimin_ )
もっと Kotlin × Spring


荻野陽太さん ( @youta1119 )
Kotlin/Nativeはなぜ動くのか?

Kotlin コルーチンを 理解しよう 2019

Ktorってなんとなく使ってみたけどこの記述は何をしているの?他のDIライブラリと何が違うの??という疑問にぴったりな講演でした。

Ktorとは?

KtorはDIをもたらすことで薄いフレームワークを作ってくれます。
よく***Application.ktに書いているinstallというブロックは機能の追加をする役割をしています。

Ktorは計算パイプラインの機構を提供しており、FeatureやRoutingの実行順序を柔軟に変更することができます。

例えば
Thread1はリクエストをするが、計算待ちの場合は他のリクエストを受け付け、
並行して走るThread2は計算ができます。
計算終了後、Thread2はThread1の処理と合流します。

suspend

別スレッドでリクエストを受け付ける事ができる

launch

ブロック内ではThread3を生成するが、終了しない場合は全てのパイプラインが実行を待つ。

async

ブロックでは別スレッドを生成し、これが終了するまで次のCallフェーズには移らない。

proceed, await

suspendしながら次のフェーズまで処理をする事ができる。最後のフェーズが終了したらまたMonitoringフェーズに戻り、全ての処理が完了したら処理が終了する。効率的に計算する事が可能。

Continuation(コールバックが入ったクラス)

suspend

コード実行を中断する可能性がある。同じサスペンドの中で呼び出す事ができる
通常の関数からはビルドエラーする
コンパイル後は引数にコールバックが入る+返り値がAnyになる

suspendの呼び方

suspendブロック内でstartCoroutineで走らせる事ができる
返り値(途中中断した場合マーカーがかえる)を持つ関数がある。

continuationを受け取る関数もある(状態の制御が可能)

マーカーを返却することで強制的にスレッドの終了が可能

ApplicationObjectをフェーズ間で共有する事ができる

Code Generation in Kotlin with Annotation and KotlinPoet

こちら外国の方の講演でした。KotlinPoetというAPIライブラリを使って、アノテーションを作っちゃおうぜというお話でした。

まず、全体的に話のレベルが高かったです。
おそらくこれはKotlinを使ってライブラリか何かを作りたい人向けのもので、
私が唯一感覚としてハマったのは、あるJsonパーサーを使っていて遭遇したキャスト関係のエラーについてくらいでした。


(正直よくわからんかったです。自分に知識が足らなすぎて…
下記内容はほぼほぼ自分の解釈+言葉遣いになるので、ニュアンスが違ったら教えてください。)


メタプログラミングについて

機能に振る舞いを加えたり、変更したりする。
ex)実行中はリフレクションやパーサーとして、コンパイル時はジェネレータとして、
実行中にファイルやプロパティを読みこむ。

ex)変数を読み込む、機能を呼び出す
xmljsonのように解釈する

保守しづらいバッドプラクティスなコードについて考えてみよう

入力に基づいてファイルを生成する
アノテーションソースコードバイトコードもしくはどのような種類のファイルでも出力できる。
安全にコンパイルする
静的にコードを解析し、実行前にエラーするのを防ぐ。

アノテーションプロセッサはJava6から加えられたAPI仕様。


@AutoMapはデータクラスをMapとして解析できるようにコンパイルしてくれます。
こやつから

@AutoMap
data class Person(
val id: Long,
val name: String?,
val address: Address
)

こう

/* *
* Converts [Person] to [Map].
*/
fun Person.toMap(): Map {
val map: Map = mapOf(
"id" to id,
"name" to name,
"address" to address
)
return map
}


kotlin-stdlibをGradleにDIすると使えます(not AndroidModule)


講演者はmetadataもオススメと話していましたが、こちらは割愛します🙇‍♂️

KotlinMetadataUtilsを実装するgetSupportedAnnotationTypesをオーバーライドする事で設定の文字列を返している。
@AutoPlocessorは別途build.gradleで追加する。


ClassNameで返り値のマップを指定できる

val returnType: ParameterizedtypeName = ClassName("kotlin.collections", "Map")
.plusParameter(String::class.asTypeName)
.plusParameter(Any::class.asTypeName().copy(nullable = true))

プレースホルダーで%T, %Mと変数をリプレース出来る
これはKotlin特有の型推論を使ったテクニック👏

if (element !is TypeElement || metadata == null) { …

mapOfの返り値を指定する
%S ->string, %L -> literal

Funspecでにアノテーションだけではなく、コメントを加えることができる。
引数の型と返り値の型、KDocを書いていく事ができる。

val mapClass = ("kotlin.collections", "Map")

val funSpec = FunSpec.builder("toMap")
.receiver()
.returns()
.addKdoc("Converts [%T] to [%T].", className, mapClass)
.addCode(codeBlockBuilder.build())
.build()

FileSpec.builder(className.packageName, className.simpleName)
.addFunction(funSpec)
.addComment("This is a generated file. Do not edit")
.build()
.writeTo(outputDir)

どんなコードができるかは101枚目のスライドを見てみましょう。

感想としては、自分たちが使っているライブラリたちは、きっとこのような過程を経て出来ていくんだなあ、と。言語特性をフル活用してコーディングする経験としてはライブラリ作成ってかなりいいのかも。
そして、完全にKotlin製のライブラリって実はOKHttp4のようにまだまだ少数派なのかも…と思い直す講演でした。

もっと Kotlin × Spring

こちらの講演は、今の現場でSpringを使うことが多い為に聴きに行きました。
別途まとめ直すかもしれません。

Kotlin/Nativeはなぜ動くのか?

CyberAgentからギークな新卒の方がお話をされにいらっしゃってました。
Kotlinをコンパイルする為に必要なミドルウェア(LVVM)のお話周りです。







f:id:letterneginr:20190912220843j:plain


f:id:letterneginr:20190912220554j:plain
KotlinFestのひよこ

前記事にも書きましたが、Kotlin界隈の方々は親しみやすく、一定数ギークな人たちが集まっているコミュニティという印象です。

そこでのエンジニアは純粋に好きなものを追いかけていて、それがどのような方向性であれ容認していくところが素晴らしいと感じています。


ちなみに、我が社のKotlin使いの先輩はGraphQL、Springなど使って管理画面を一新するそうです。。
酒の誘惑に負けずに共に頑張りましょう(私自身、酒はそんなに飲みませんが…)


私はもう少しSpringとお友達になることにします🌸