Kotlin 1.3.70変更点まとめ

# はじめに
Kotlin 1.3.70がリリースされたため、変更点を自分なりにまとめました。

正確な情報は[公式情報](https://blog.jetbrains.com/kotlin/2020/03/kotlin-1-3-70-released/)を確認してください。
特に標準ライブラリ以外のまとめはかなり雑です…


# 標準ライブラリの変更点
## StringBuilderの拡張
`kotlin.text` パッケージ内のStringBuilderにメンバーが追加されました。今までJVMに依存していたメンバーなども追加されているようです。
（詳細までは不明。[公式ドキュメント](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.text/-string-builder/index.html)を参照）

## KClass
`kotlin-reflect` に依存していたKClassのいくつかのメンバーが依存しなくなったようです。
公式から引用した以下のコードをそのまま実行すると、1.3.60では `KotlinReflectionNotSupportedError` というエラーが出ますが、1.3.70では出なくなっています。
（IDE上で警告は出てますが実行は可能です）

```kotlin
fun main() {
    val kClass = String::class
    println(kClass.simpleName) // String
    println(kClass.qualifiedName) // kotlin.String

    println(kClass.isInstance("abc")) // true
    println(kClass.isInstance(10)) // false
    println(kClass.cast("abc")) // abc
}
```

## @Experimentalおよび@UseExperimentalの名称変更
今まで実験的な機能には `@Experimental` もしくは `@UseExperimental` というアノテーションを付ける必要がありましたが、それぞれ `@OptIn` と `@RequiresOptIn` という名称に変更になったようです。

また、それに伴いコンパイラ引数 `-Xuse-experimental` が `-Xopt-in` という名前に変更されました。

`@Experimental` と `@UseExperimental` はKotlin 1.4では削除されるとのことです。

## 時間測定APIの名称変更
時間測定用の `Clock` 、`ClockMark` というAPIが`TimeSource` 、 `TimeMark` という名前に変更されたようです。
今までのAPIは非推奨として残されています。
`Clock` については[こちら](https://blog.jetbrains.com/kotlin/2019/08/kotlin-1-3-50-released/#time-measurement-api)

## 両端キューArrayDequeの実装
「始端」と「終端」の概念がある配列 `ArrayDeque` が実装されたようです。
FIFOなど、キューやスタック処理の実装がやりやすくなると思われます。

```kotlin
@OptIn(ExperimentalStdlibApi::class)
fun main() {
    val deque = ArrayDeque(listOf(1, 2, 3))

    deque.addFirst(0)
    deque.addLast(4)
    println(deque) // [0, 1, 2, 3, 4]

    println(deque.first()) // 0
    println(deque.last()) // 4

    deque.removeFirst()
    deque.removeLast()
    println(deque) // [1, 2, 3]
}
```

## Collection builderの実装
`buildList` 、 `buildSet` 、 `buildMap` などの関数が追加されました。
これは `buildList` であれば 

```kotlin
val items = buildList { ... }
```
の中でだけは `MutableList` として扱われ、その後は読み取り専用の `List` として扱える変数を定義することが出来る関数です。
LiveDataの LiveData Builder と似たような役割を持っていると言えます。

```kotlin
fun main() {
    val needsZero = true
    val initial = listOf(2, 6, 41)

    val ints = buildList { // this: MutableList
        if (needsZero) {
            add(0)
        }
        initial.mapTo(this) { it + 1 }
    }
    println(ints) // [0, 3, 7, 42]
}
```

## reduceOrNull()及びrandomOrNull()への対応

`reduce()` や `random()` した時、結果がnullの場合は例外が返されますが、結果がnullの時にnullを返すオペレーション `reduceOrNull()` 及び `randomOrNull()` が追加されました。

```kotlin
@OptIn(ExperimentalStdlibApi::class)
fun main() {
    val list = listOf(1, 2, 3)
    println(list.randomOrNull()) //
    println(list.reduceOrNull { a, b -> a + b }) // 6

    val emptyList = emptyList()
    println(emptyList.randomOrNull()) // null
    println(emptyList.reduceOrNull { a, b -> a + b }) // null
}
```

## scan()関数の実装
新たに `scan()` という関数が実装されたようです。
これは `fold()` と似ていますが、 `fold()` は結果だけを返すのに対し、 `scan()` は中間の結果も含めて返すという違いがあるようです。

（ここは結構複雑なのと、fold()をほとんど触ったことがないので[公式](https://blog.jetbrains.com/kotlin/2020/03/kotlin-1-3-70-released/)を見て頂いた方がわかりやすいと思います…）


```kotlin
@OptIn(ExperimentalStdlibApi::class)
fun main() {
    val ints = (1..4).asSequence()
    println(ints.fold(0) { acc, elem -> acc + elem }) // 10

    val sequence = ints.scan(0) { acc, elem -> acc + elem }
    println(sequence.toList()) // [0, 1, 3, 6, 10]
}
```

# IntelliJ IDEAのサポート
以降はIntelliJ IDEAにおけるKotlinサポートの改善点です。

## * .gradle.ktsサポート
IntelliJ IDEAでのGradle Kotlin DSLスクリプトファイル(* .gradle.kts)のサポートが改善されました。

## コード補完機能の強化
IntelliJ IDEAでのKotlinコード補完に「顕著な改善」を加えたそうです。補完候補の並べ替えなども強化されているようです。

## 新しいカラースキーム
サスペンド関数呼び出しやプロパティ宣言に独自のカラースキームを設定できるようになったそうです。

## デバッグの改善
Kotlin/Nativeのデバッガーのブレークポイントタイプが複数あり、どちらを使えば良いのかユーザーを混乱させていたのを改善した？とのことです。

## Kotlin/JSとKotlin/Nativeのテスト
Kotlin/JSとKotlin/Nativeのテスト結果が、Kotlin/JVMテストと同様にIntelliJ IDEAに表示されるようになったようです。

## その他の改善
- ファイル解析やコピー＆ペーストパフォーマンスの改善
- 無意味な単項演算子の検査
- 書式設定の改善多数

# Kotlin/JVM

targetVersion1.8以降のJVMバイトコードで、タイプアノテーションを生成できるようになりました。
これにより、既存のJavaライブラリの使用がはるかに簡単に出来るようになったようです。

公式コードでは、 `@Foo` アノテーションでString型をバイトコードに出力するサンプルが公開されています。

```kotlin
@Target(AnnotationTarget.TYPE)
annotation class Foo

class A {
    fun foo(): @Foo String = "OK"
}
```

# Kotlin/JS

## バンドルの最適化
Kotlin/JSではバンドルサイズについて、いくつかの最適化が行われたようです。
developビルドとreleaseビルドのバイナリサイズの比較が公開されています。

| Project | Development Build (gzip) | Production Build (gzip)   |
| -------------------------------- | ----------------------- | ------ |
| “Hello, World”                   | 963 KiB                 | 14 KiB |
|Kotlin/React Example (“CodeQuiz”) | 4.1 MiB                 | 345 KiB|

## リソースの自動コピー
配布フォルダーにバンドルを作成するビルドタスク`browserProductionWebpack` などで、`resources` フォルダーからすべてのアセットを自動コピーするようになったようです。
画像やスタイルシートを手動コピーする必要が無くなったとのこと。

## npmの依存関係のよりスムーズなサポート
Gradleプラグインのトップレベルの `dependencies` ブロック でnpmの依存関係を宣言できるようになったそうです。

```groovy
dependencies {
    implementation(npm("react", "16.12.0"))
}
```

## Gradleによる実験的なテストデバッグ
IntelliJ IDEAからテストを直接デバッグ出来るようになった？らしいです。

## ドキュメントの改善
JavaScriptターゲットのドキュメントとチュートリアルに変更が加えられ、より簡単にKotlin/JSを使い始められるようになったそうです。
簡単な[チュートリアル](https://kotlinlang.org/docs/tutorials/?_ga=2.104545408.1253780874.1583284898-669839662.1574150871)も公開されています。

# Kotlin/Native

## パフォーマンスの最適化
コンパイル時間の短縮や、ランタイム、デバッグパフォーマンスなどの改善が行われたようです。

## 単一アプリケーションでの複数Kotlinフレームワークのサポート
Obj-Cクラスの競合によって、複数のKotlin/Nativeフレームワークを使用できない問題が解決されたようです。

## ベクタータイプのサポート
1.3.70からSIMDタイプをサポートするようになりました。
これにより、Appleのフレームワーク [Accelerate](https://developer.apple.com/documentation/accelerate) や [SpriteKit](https://developer.apple.com/documentation/spritekit) を使えるようになったようです。

# Scripting

以下公式より抜粋：
1.3.70では、IntelliJ IDEAおよびKotlinコマンドラインツールでのKotlinスクリプトの使用について、より良いエクスペリエンスを提供するために改善を行いました。

Kotlinスクリプトに慣れるための[サンプルプロジェクト](https://github.com/Kotlin/kotlin-script-examples)も用意しています。

## kotlin-main-kts コンパイラおよびIDEでのサポート
Kotlin 1.3では、基本的なユーティリティスクリプトの作成と使用を簡易化する[kotlin-main-ktsアーティファクト](https://github.com/Kotlin/KEEP/blob/master/proposals/scripting-support.md#kotlin-main-kts)を導入しました。
コンパイルされた `*.main.kts` スクリプトのキャッシングを有効にすることで、スクリプトの実行パフォーマンスを改善しました。

## コマンドラインツール
コマンドラインツールでのKotlinスクリプトのサポートを拡張しました。

# おわりに
わかりにくい、訳が違うなどのご指摘はどんどんください。
Collection builderやArrayDequeはかなり便利な機能だと思うのでぜひ使っていきたいです。

さあみんなもLet’s Kotlin!