ぽんぽんぺいんでつらたんなので、おしごとおやすみしまーす

🗣: バイクに乗ったり、ものづくりしたり、ひたすら寝たり。

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

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

新職場1週間目でした🎉🎉🎉 環境構築諸々など無事に済んでよかった。

今回はなんと会社のお金で週末にKotlinFestに参加する権利をいただき、エンジニアらしい行事に参ずる事ができて感無量でした。

小さな勉強会にはちょくちょく参加していましたが、Kotlin書く人達(Kotler?)は温和で親しみやすい雰囲気でありながら、ギークな部分が垣間見える面があり、非常に良い雰囲気の中で勉強させてもらいました。

断片的ではありますが、内容をまとめていきたいと思います。 自分が聞いたのは下記の5セッションです。

1. オープニングセッション
長澤太郎
Svetlana Isakova

2. Server-side Kotlin by Ktor
Coroutinesから紐解くKtorの仕組み
小谷野 雄史

[EN]
3. Code Generation in Kotlin with Annotation and KotlinPoet
Malvin Sutanto

4. もっと Kotlin × Spring
木原 快

5. Kotlin/Nativeはなぜ動くのか?
荻野陽太

オープニングセッション

遅刻したもので、長澤さんが「Have a nice Kotlin !!」という部分からの参加になってしまったorz Svetlana IsakovaさんはJetBrains社(Kotlinを開発した会社の人)らしく、これまでのKotlinの進化についてや、魅力的な機能を紹介してくださっていた。

Kotlinは既存のコードを壊さないような構造をしている

まだ自分の経験の中で実感できてはいないが、前の職場ではJavaのリプレースをKotlinで少しずつやっていて、共存が出来ていたので確かにこれは便利なものだと思っている。

コミュニティでは常に問題共有を行い、対応していくことを考えている

コミュニティについては、プロダクトコードをほとんど書いていなかったこともあり、胸を張って参加する事が出来ていなかったが、今後は積極的に情報のキャッチアップをしたい。(特にJavaの方も)

Kotlinをより良いプロダクトにする為にみなさんからフィードバックが欲しい

とのことで、いくつかの機能について紹介をいただく。

  • inline class
  • extention property
  • immutable collection
  • flow(experimental)
  • multi platform project

改めて思ったのは、本当にKotlinの言語仕様わかってなさすぎた… 他のエンジニアと自分のコードを見比べたり、客観的にアドバイスいただいて思うことはこの知識量の差でもあるなと実感。 Kotlinの良さをしっかり理解してコードを書くというよりも、今まではAndroidの機能を実装するということにウェイトを置いてしまっていたと実感した。

今はSvetlanaさんは新しいKotlinの本を執筆されているそうで(仮タイトルはAtomic Kotlinだったかな)、これはプログラミング初心者や、Java初心者でもついていけるような内容にしていくそう。

初めて型言語の大きな勉強会に参加したけど、Railsやフロントエンドの時よりも、女性エンジニアが少ないのが少し気になったのよね。 もう少し同士が増えたら嬉しいななんて思う。

www.coursera.org ちなみに、こちらのCouseraからAuditモードでKotlinの学習ができるそうです。

基調講演のSvetlanaさんのスライドはこちら

基調講演での技術紹介

ここからは聞き取れた内容と、Svetlaさんのスライドを雑に訳す+補足情報を加える事で自分が解釈できた情報を書いていきます。 まだ実際に試していない内容になるので、ご注意ください。 サンプルコードについては、スライドより抜粋させていただきました。

- inline class

オーバーヘッドなしに値をラップできる いまは実験段階

Duration APIは1.3.50で実験的に提供される

同じ関数を違う型で扱いたい時、その分だけオーバーロードするには冗長的すぎる。 そんな時、クラスでラップしてあげれば他の方のオブジェクトも割り当てる事ができる。

inline classを定義し、下部で関数を定義できる。

また、inline classではval(再代入不可)なコンストラクタしか宣言ができない。

この性質を利用して、明示的な単位を設定することができる。

val Int.seconds
  get() = toDuration(DurationUnit.SECONDS)
fun greetAfterTimeout(duration: Duration)
greetAfterTimeout(2.seconds)

- contract

日本語で契約、約定という意味。 スコープ関数として定義され、自身をレシーバとした関数を実施し、その内容を返す。 しかし、runブロックの中で初期化をしてしまうとコンパイラがそれを検知できない為、エラーを返す。(これについては仕様。後述する。)

isNullOrEmpty()についても同様。 レシーバにヌル許可を割り当てた場合、これを検知する為にエルビス演算子を挿入する必要がある。

しかし、contractsはコンパイラに明示的にコードのその他の情報を共有する。

ブロック内では1度きりのみ呼ばれるようになり、

関数が偽を返せば、レシーバがヌル不可であると解釈する。

これを利用してrunブロックでの変数初期化、エルビス演算子なしでの解釈が可能となる。

なぜコンパイラに情報が不足した状態だったのか 

それに依存する事でコードが壊れることを防ぐ為。

contractsを使うことでrunとisEmptyOrNullは便利になるし、独自に関数で定義できるようになる為便利ー。

- immutable collection

ImmutableListにPersistentListというキャストに便利な仲間が加わるよ。

オリジナルのリストデータ構造の一部を共有している。 なんとaddができる。ハッピー。

val list = persistentListOf(1, 2, 3)
val newList = list.builder().apply {
  add(4)
  add(5)
}.build()
println(newList) // [1, 2, 3, 4, 5]

- flow(experimental)

ReactiveStreamを基礎としたsuspend?

flow { emit(value) } 
  .map{}
  .filter{}
  .catch{}
  .collect{}

RxJavaとの統合

flow.asPublisher()
publisher.asFlow()

suspendのメカニズムによってBackpressureが起こります。

->余談 : BackPressureとは

https://github.com/Kotlin/kotlinx.coroutines/blob/master/reactive/coroutines-guide-reactive.md

https://qiita.com/pljp/items/f748125934fd3f880565 (上記の日本語訳)

同じ処理を追随させて別のスレッドで行わせる事ができる。メインスレッド側の最後の処理が終了した後、別スレッドの処理も完了する挙動をする。

Flowableとは

データの流れを消費する事ができる、ファクトリーメソッドとReactive Streams Patternを実装している。 PublisherとReactive StreamsはFlowableの継承をしていて、別のReactive Streamの操作とPublisherを直接的に受付けている。

- multi platform project(expect actual)

expect fun Char.isUpperCase(): Boolean
public actual fun Char.isUpperCase(): Boolean

ビジネスロジックを共有できる プラットフォーム依存のUIを保てる (共有部分は異なるかもしれない)

expectは共通部分に宣言する事ができる。 異なるプラットフォームにはactualが宣言できる。

共通部分については標準的なライブラリで使う事ができる。

標準的なもの、KtorHTTP client、serialization、couroutinesなどなど… すでに本番環境で動いている事例もあります。

マルチプラットフォームにモダンなアプローチをしています。

このように、共有したい部分を調整できます。

引用:

qiita.com