QOLうなぎ登りなKotlin Tips提案

プログラミング言語Kotlinは、今年特にAndroiderの間で注目を集めました。
実際今月だけでも多くの方がKotlinに関する記事を書かれています（すごい！）。

Kotlinについて詳しく知りたい方は[公式サイト](https://kotlinlang.org/)を参照してください。
雰囲気を掴みたい方は「[Android開発を受注したからKotlinをガッツリ使ってみたら最高だった](http://qiita.com/omochimetaru/items/98e015b0b694dd97f323)」を、最新動向や込み入ったトピックに興味のある方は[Kotlin Advent Calendar 2015](http://www.adventar.org/calendars/857)を見てください。
日本語による書籍ですと[Software Design](http://gihyo.jp/magazine/SD/archive/2015/201504)で一時期連載がありました。単行本は目下執筆中です。

さて、本題です。
このようにKotlinユーザは増えてきているようですが、Kotlinはまだ若いことと、（Javaと比較して）機能が多いだけあってイディオムやパターンめいたものが定着していないように感じます。
ごく基本的なイディオムについては[公式サイト](https://kotlinlang.org/docs/reference/idioms.html)で示されているので、ここでは別視点というかもっと攻めたコードを紹介したいと思います。
これが正解だっ！というつもりはなく、あくまで提案なので意見があればどんどんコメントください！（もしくは[SlackのKotlin日本語部屋](http://kotlinlang-jp.herokuapp.com/)で議論するのも面白いでしょう。）

## nullはifでチェックすればいいんだよ

まずは簡単なトピックから始めましょう。
結論から言うと、`if`で`null`チェックすることは悪いことではない、ということです。

少し長くなりますが、背景を。
Javaには値の有無を表現する型`Optional`があります。
次のコードは避けたい書き方です。

```java
// Java
final Optional<User> user = findUser();
if (user.isPresent()) {
    show(user.get());
}
```

`Optional#get`はKotlinで言う`!!`と同じ操作だからです。
こう直すべきでしょう。

```java
// Java
user.ifPresent(u -> show(u));
user.ifPresent(this::show); // この例の場合はこちらも可
```

KotlinにはJavaの`Optional#ifPresent`と似たことができる`let`という拡張関数が提供されています。

```kotlin
val user: User? = findUser()
user?.let { show(it) }
user?.let(::show) // この例の場合はこちらも可
```

Javaの話のようにKotlinでも`let`を使い`if`での条件分岐はNG！ということはありません。
何故ならKotlinは、`if`で`null`でないことを確認した後は、その変数をNotNullとして扱えるからです。

```kotlin
if (user != null) {
    show(user)
}
```

Javaのように`if`ブロック内で`user!!`のような危険な操作をする必要がないのです。
基本的には`let`などを使った方が奇麗に記述できる場合が多いですが、例えば複数のNullable変数をNotNullとして扱いたいときに`if`は重宝します。

```kotlin
// ifバージョン
if (firstName != null && lastName != null) {
    save(firstName, lastName)
}

// letバージョン
firstName.let { first ->
    lastName.let { last ->
        save(first, last)
    }
}
```

## 流れるようなインタフェース？

Builderパターンのようにメソッドをチェーンさせて値をセットさせていく、いわゆる「流れるようなインタフェース」をJavaのライブラリではよく目にします。
これをそのままKotlinで使っても、すごく奇麗なコードになります。
しかしKotlinの機能をもっと活用するように改良してみたいと思います。

### 名前付き引数

大抵の場合はこれで解決です。

```kotlin
data class Person(
    val name: String,
    val age: Int,
    val address: String
)

val taro = Person(
    name = "たろう",
    age = 27,
    address = "葛西"
)
```

### Builderクラス

```kotlin
data class Person(
    val name: String,
    val age: Int,
    val address: String
) {
    class Builder {
        var name: String? = null
        var age: Int? = null
        var address: String? = null
        
        fun build(): Person =
            Person(
                name = requireNotNull(name),
                age = requireNotNull(age),
                address = requireNotNull(address)
            )
    }
    
    companion object {
        fun build(f: Builder.() -> Unit): Person {
            val builder = Builder()
            builder.f()
            return builder.build()
        }
    }
}

val taro = Person.build {
    name = "たろう"
    age = 27
    address = "葛西"
}
```

## [Deprecated] 拡張関数の使用にあえて手間をかけさせる

Kotlinの特に面白い機能のひとつに拡張関数というものがあります。
既存の型にメソッドを生やすような機能です。
実際には既存の型を書き換えることはせず、静的に解決されるので混乱の種にはなりにくいかも知れません。
名前に関しても同じことが言えます。
例えば`Context`に対して`toast`という拡張関数をパッケージ`foo`と`bar`でそれぞれ定義したとき、パッケージ`baz`配下で`toast`を使用する際には`foo`の実装を使うのか、それとも`bar`の実装を使うのかインポートを行って明示する必要があります。

```kotlin
package baz
import foo.toast
// その他のインポート文は省略

class MainActivity: Activity() {
    override fun onResume() {
        super.onResume()
        toast("Hello")
    }
}
```

ここで問題提起ですが、インポート文でどの実装を使っているかを明記するだけで十分でしょうか？
コンパイラ的にはなんの問題もないのですがプログラマにとってはわかりやすいコードになっているのでしょうか？
この答えを「インポート文はノイジーになりがちで、プログラマにはわかりにくい」ということにすると、どのような解決策があるでしょうか。

提案: インタフェースに拡張関数を定義してみる

```kotlin
package foo
interface FooToast {
    fun Context.toast(msg: String) {
        // トースト表示
    }
}
```

```kotlin
package baz
import foo.FooToast

class MainActivity: Activity(), FooToast {
    override fun onResume() {
        super.onResume()
        toast("Hello")
    }
}
```

`FooToast`の名前には改良の余地がありますが、こんな具合です。
拡張関数の`toast`の名前空間としてインタフェースを噛ませて、ちょっと手間はかかるけど、わかりやすくなっているように感じます。

## カリー化

ここで主張したいことはこうです:

* 拡張関数は既存の型に対してメソッドを生やす
* `operator`付き`invoke`メソッドを持ったオブジェクトは、関数呼び出しのようなシンタックスシュガーを持つ（`obj.invoke()`は`obj()`と同じ）
* 関数にも型がある

これらを組み合わせるとDSLを開発するときに役立つでしょう。
DSLとは違いますが、例えば関数のカリーは次のコードのように表現できます。

```kotlin
operator fun <A, B, C> ((A, B) -> C).invoke(a: A): (B) -> C = { a(it) }

val minus = fun(a: Int, b: Int): Int = a - b
minus(5, 3) //=> 2
minus(5)(3) //=> 2
```

1行目では型`(A, B) -> C`すなわち2引数関数に対して`invoke`という名前（そして引数はひとつ）のメソッドを生やしています。
これにより関数がデフォルトでカリー化されているように見えるわけです。

## `!!`を避ける (2016-01-03追記)

あるNullable値をNotNullに変換したい場合、たいていは`if`によるチェックか`let`拡張関数を使えば事足ります。しかし、Nullable値がNotNullに仕様上必ず変換可能であるべきシーンがあります。そんなとき、Nullable→NotNullの強制変換演算子である`!!`を使うことは避けるべきです。代わりに`requireNotNull`関数か、エルビス演算子 + 例外スローを使いましょう。NotNullに変換する理由をコードで明示的に表現するというわけです。

```kotlin
// !!を使う場合 ↓のようにコメントは欠かせない
// ここでuserは絶対にNotNullである
save(user!!)

// requireNotNullを使う場合
save(requireNotNull(user, {"userはNotNullであるべきなので何かがおかしい"}))

// エルビス演算子 + 例外スロー(実際の例外クラスは状況に応じて選択)
save(user ?: throw IllegalStateException("何かがおかしい"))
```

## 特定のコンテキスト内ではたらく拡張関数 (2016-02-02追記)

先日の[AndroidでKotlin勉強会 @ Sansan](http://jp.corp-sansan.com/blog/hitokoto/2016/160129.html)で発表したスライドです↓

https://speakerdeck.com/ntaro/androiddekotlinhuruhuo-yong-puroguramingu-number-kotlin-sansan

拡張関数って、当たり前ですがレシーバが1つだけなのが不便ですよね。
しかし2つの型に依存したような拡張関数を作れますよ、というのがこの発表の内容です。
アプローチとしては、インタフェース内で拡張関数を定義して、それをimplementsする感じです。

もう1つ別のアプローチを見つけました。
それは、「拡張関数を返す拡張プロパティ」を定義することです（double context extensionパターンと勝手に命名）。
詳細は[こちらのエントリ](http://taro.hatenablog.jp/entry/2016/02/02/141551)を参照。

## おわりに

いかがでしたか？
なるほどと思えるものがあったら嬉しいです。
反論や改善案があったらぜひコメントしてください。

Kotlinに興味を持っていただけたら、来年1月にある[AndroidでKotlin勉強会 ＠ Sansan](http://connpass.com/event/22189/)や2月にある[DroidKaigi 2016](https://droidkaigi.github.io/2016/)に参加してみてください！