[ことクロ4] ”Kotlin in Action”本 1章、2章の例題コード

"Kotlinでスマートフォン・クロスプラットフォーム開発入門"、勝手に略して、"ことクロ"シリーズ　その４。

今回は、JetBrains社の中の人が執筆中のKotlin書籍["Kotlin in Action"](https://www.manning.com/books/kotlin-in-action)の無料版PDF第1章Kotlin: What and Why本文と２章以降のコードをちら見。書籍の対象読者は、既にJavaを知っている人とのこと。
...以下は、groovyとかscalaとか、その手の言語をちょっと使ったことがある人視点でのメモ。

#第1章　Kotlin: What and Why 
Kotlinの良さを概観する章。本家サイト等にある記述を改めて述べているところが多いので、コード例を中心に見ていくこととする。

## 1.1 A Taste of Kotlin
１章唯一の例題コードが以下:

```ATasteOfKotlin.kt
package ch01.ATasteOfKotlin

data class Person(val name: String,
                  val age: Int? = null)

fun main(args: Array<String>) {
    val persons = listOf(Person("Alice"),
                         Person("Bob", age = 29))

    val oldest = persons.maxBy { it.age ?: 0 }
    println("The oldest is: $oldest")
}
```

- data classは、scalaでいうcase classに相当する。
- listOfやmaxByといった前置詞を使った記法はscalaの記法に馴染んだ身としては、ちょっと新鮮。
- 高階関数でのit.ageを値ありかnullかで扱っている記法は三項演算子の類推なのだろう。

##1.2 Kotlin’s Main Traits
kotlinのターゲットプラットフォームに、Javaが動く環境のほかに、RoboVMを介してのiOSを明記。RoboVMにIDEを提供しはじめたJetbrains社としては、押して行きたいところなのだろう。その後は、静的型・関数型・オブジェクト指向、そして、無償・オープンソースであるといった特徴を記述。
##1.3 The Applications of Kotlin
サーバ側では、既存のJavaコードとの相性の良さを記述。HTMLを生成するDSLコードを例示し、Jetbains社の[Exposed](https://github.com/JetBrains/Exposed)というKotlin製SQL用JDBCラッパーのコードを例示。object/classの組み合わせでの記述は、ScalaのMapper ORM(?)をちょっとほうふつさせる。擬似コードなのでチラ見に留める。

ついで、Android環境の紹介。Jetbains社のUI記述DSL[Anko](https://github.com/jetbrains/anko)を紹介。ちょっと気になる。
##1.4 The Philosophy of Kotlin
Kotlinは、実用的で、簡潔で、安全で、(Javaと)相互運用的ですよ、と。

##1.5 Using the Kotlin Tools
実行環境の紹介など。

##1.6 Summary
要約。
#第2章　Kotlin Basics
```２章.章立て
2. KOTLIN BASICS
2.1. Basic Elements
2.1.1. Hello, world!
2.1.2. Easier String Formatting: String Templates
2.1.3. Functions
2.1.4. Variables
2.2. Classes and Properties
2.2.1. Properties
2.2.2. Custom Accessors
2.2.3. Changing Accessor Visibility
2.3. New Ways to Switch: 'when'
2.3.1. Using when for dealing with enum classes
2.3.2. 'when' Without Argument
2.3.3. Using when and smart casts for dealing with class hierarchies
2.3.4. Refactoring: replacing if with when
2.3.5. Blocks as Branches of if and when
2.4. Iterating over Things: 'while' and 'for' Loops
2.4.1. The while Loop
2.4.2. Ranges and Progressions
2.4.3. Iterating over Collections and Maps
2.4.4. 'in' check
2.5. Exceptions in Kotlin
2.5.1. 'try', 'catch' and 'finally'
2.5.2. 'try' as expression
2.6. Summary
```
本文はMEAP購読しなくてはならないが、コードは公開されているので、興味をもったものを本家の[オンライン実行環境](http://try.kotlinlang.org/)にて試していく。オンライン環境でしっかり実行できるね。

```10.kt
enum class Color {
    RED, ORANGE, YELLOW, GREEN, BLUE, INDIGO, VIOLET
}

fun getMnemonic(color: Color) =
    when (color) {
        Color.RED -> "Richard"
        Color.ORANGE -> "Of"
        Color.YELLOW -> "York"
        Color.GREEN -> "Gave"
        Color.BLUE -> "Battle"
        Color.INDIGO -> "In"
        Color.VIOLET -> "Vain"
    }


fun main(args: Array<String>) {
    println(getMnemonic(Color.BLUE))
}
```

enum classという列挙クラス表記がなにか新鮮だが、意味は分かる。
Color.MINTなどColorにない属性を与えてコンパイルしようとすると、エラーとなる。
Kotlinのコンパイル段階でのチェックを紹介するためのコードなのだろう。

```11.kt
enum class Color {
    RED, ORANGE, YELLOW, GREEN, BLUE, INDIGO, VIOLET
}

fun mix(c1: Color, c2: Color) =
        when (setOf(c1, c2)) {
            setOf(Color.RED, Color.YELLOW) ->
                Color.ORANGE
            setOf(Color.YELLOW, Color.BLUE) ->
                Color.GREEN
            setOf(Color.BLUE, Color.VIOLET) ->
                Color.INDIGO
            else -> throw Exception("Dirty color")
        }


fun main(args: Array<String>) {
    println(mix(Color.BLUE, Color.YELLOW))
}
```
Cのswitchテイストなwhen文の解説か。
main関数中に、println(mix(Color.BLUE, Color.PINK))を追加するとコンパイルエラー
println(mix(Color.BLUE, Color.RED))を追加すると、以下の実行時例外が生じる。

```
Exception in thread "main" java.lang.Exception: Dirty color
    at Simplest_versionKt.mix(Simplest version.kt:13)
    at Simplest_versionKt.main(Simplest version.kt:19)
    at _DefaultPackage.main(Simplest version.kt:1)
```
when文は、koltinにおいて、例外処理を含む記述に多用されるのだろう。
さらなる例題が、interfaceの使い方に注目。

```17.kt
interface Expr
class Num(val value: Int) : Expr
class Sum(val left: Expr, val right: Expr) : Expr

fun evalWithLogging(e: Expr): Int =
    when (e) {
        is Num -> {
            println("num: ${e.value}")
            e.value
        }
        is Sum -> {
            val left = evalWithLogging(e.left)
            val right = evalWithLogging(e.right)
            println("sum: $left + $right")
            left + right
        }
        else -> throw IllegalArgumentException("Unknown expression")
    }

fun main(args: Array<String>) {
    evalWithLogging(Sum(Sum(Num(1), Num(2)), Num(4)))
}
```
実行結果と照らし合わせると興味深いので、実行してみてほしい。

次いで、fizzBuzz問題のwhen文を使って解く。

```18.kt
fun fizzBuzz(i: Int) = when {
    i % 15 == 0 -> "FizzBuzz "
    i % 3 == 0 -> "Fizz "
    i % 5 == 0 -> "Buzz "
    else -> "$i "
}

fun main(args: Array<String>) {
    for (i in 1..100) {
         print(fizzBuzz(i))
    }
}
```

次いで、java.util.TreeMapを使ったお題。Javaとの互換性を確認する意味で実行してみても良いだろう。

```19.kt
import java.util.TreeMap


fun main(args: Array<String>) {
    val binaryReps = TreeMap<Char, String>()

    for (c in 'A'..'F') {
        val binary = Integer.toBinaryString(c.toInt())
        binaryReps[c] = binary
    }

    for ((letter, binary) in binaryReps) {
        println("$letter = $binary")
    }
}
```

その後、java.io.BufferedReaderを使った例題コードが続くがこちらは、ブラウザ環境では動かなかった。IntelliJ等でコンパイルしローカル環境では動くのだろう。

# 感想
ブラウザ上ですぐにコードを動かせるのは、非常に有意義。Kotlinに興味がある方には、今後、公開されるコードが増えた後に、どんどん実行してみて、この本を買う価値があるかどうか判断してみることをおすすめしたい。

## 付記
Action本サイト右下にReviewer募集があってちょっと気になっている。長くなってきたので、３章以降は続きにて。