「プログラマに優しい現実指向JVM言語 Kotlin入門」で勉強して、、、（その１）

「[プログラマに優しい現実指向JVM言語 Kotlin入門](https://gihyo.jp/dev/serial/01/jvm-kotlin/0003)」でKotlinを勉強しはじめました。
　説明が丁寧で、分かりやすいです。ただ一部、ソースコードの動作を確認しようとしたときに、mainルーチンがなかったりしたので、その部分を追記しました。（自分で悩まなかった部分は、飛ばしています。）
　説明など有益な情報をぜひ、[原文](https://gihyo.jp/dev/serial/01/jvm-kotlin/0003)でご確認ください。

## リスト12　デフォルト引数

```Kotlin:Function05.kt
fun hello(name: String, exclamation: Boolean = false) {
  val suffix = if (exclamation) "!" else ""
  println("Hello, ${name}${suffix}")
}
	
fun main() {
    hello("Kotlin")
    hello("Kotlin",true)
    hello(exclamation = false, name = "Baz")
}
```

## リスト15　forによるループ

```Kotlin:Function06.kt

fun sum(ints: List<Int>): Int {
  var sum = 0
  for (e in ints) {
    sum += e
  }
  return sum
}

fun main() {
    println(sum(listOf(1,2,3)))
    // 書き砕くと
    val data = listOf(4,5,6)
    val a = sum(data)
    println(a)
    // https://qiita.com/kiririnyo/items/aee905225902d096f7c0 リストの使い方参考
}

```

## リスト16　再帰呼び出しによるループ

```Kotlin:Function07.kt
fun sum(ints: List<Int>): Int =
    // if da(ints.isEmpty()) 0  //原文では、左のようにda()と記述されていたが、誤記と判断
    if (ints.isEmpty()) 0
    else ints.first() + sum(ints.drop(1))

fun main() {
    println(sum(listOf(1,2,3)))
    // 書き砕くと
    val data = listOf(4,5,6)
    val a = sum(data)
    println(a)    
}
```


## リスト18　末尾呼び出し最適化が効くgcd関数

```Kotlin:Function09.kt
// 大きい方を返す
fun max(a: Int, b: Int): Int = if (a < b) b else a

// 小さい方を返す
fun min(a: Int, b: Int): Int = if (a <= b) a else b

//tailRecursive fun gcd(a: Int, b: Int): Int {		//誤記？tailRecursiveの部分
tailrec fun gcd(a: Int, b: Int): Int {
    val x = max(a, b)
    val y = min(a, b)
    return if (y == 0) x
            else gcd(y, x% y)
} 

fun main() {
    val data = gcd(20,16)
    println(data)    
}

//＜参考：末尾再帰の使い方＞　https://sites.google.com/site/memo73737/kotlin/tailrecursive
```

## リスト19・20まとめ　関数オブジェクト　と　invokeメソッド

```Kotlin:FuncObj01.kt
fun main() {
    //リスト19　関数オブジェクト
    fun succ(n: Int) = n + 1
    val hoge = ::succ
    
    //リスト20　invokeメソッド
    val r = hoge.invoke(5)
    println(r) // => 6
    
    //リスト21　invoke呼び出しの構文糖衣
    val s = hoge(10)
    println(s) // => 11
}

```

　また、次の例はsucc関数をmain()の外に出した例です。succの外に置くのが正しいのか、内側に置くのが正しいのか、原文から読み取れませんでした。(追記：この疑問について、@sdkeiさんがコメントをくださっています。下のコメント欄をご確認ください。）


```Kotlin:FuncObj01b.kt
// https://gihyo.jp/dev/serial/01/jvm-kotlin/0003?page=3

//リスト19　関数オブジェクト（その１／２）：succ関数をmain()の外に出した例
fun succ(n: Int) = n + 1

fun main() {
    //リスト19　関数オブジェクト（その２／２）
    val hoge = ::succ
    
    //リスト20　invokeメソッド
    val r = hoge.invoke(5)
    println(r) // => 6
    
    //リスト21　invoke呼び出しの構文糖衣
    val s = hoge(10)
    println(s) // => 11
}
```

##リスト23　高階関数の例　と　リスト24　apply関数を使う（まとめ）

```Kotlin:FuncObj02.kt
// https://gihyo.jp/dev/serial/01/jvm-kotlin/0003?page=3

//リスト23　高階関数の例
fun apply(n: Int, f: (Int) -> Int) : Int {
    println("開始")
    val r = f(n)
    println("終了")
    return r
}

//リスト19　関数オブジェクト
fun succ(n: Int) = n + 1

fun main() {
    //リスト24　apply関数を使う
    val got = apply(5, ::succ)
    println(got) // => 6
}
```
## リスト25　リストの各要素を変換して新しいリストを得るmap関数　と　リスト26　map関数を使う　（まとめ）
```Kotlin:FuncObj03.kt
//https://gihyo.jp/dev/serial/01/jvm-kotlin/0003?page=3

//リスト25　リストの各要素を変換して新しいリストを得るmap関数
fun map(ints: List<Int>, f: (Int) -> Int): List<Int> {
  val newList = java.util.ArrayList<Int>()
  for (e in ints) {
    newList.add(f(e))
  }
  return newList
}

//メインルーチン
fun main(){
    //リスト26　map関数を使う
    // [2, 3, 4]のリストを作る
    val src = listOf(2, 3, 4)

    // 平方を得る関数を各要素に適用
    fun square(n: Int): Int = n * n
    println(map(src, ::square)) // => [4, 9, 16]

    // 階乗を得る関数を各要素に適用
    fun factorial(n: Int): Int =
        if (n == 1) 1
        else n * factorial(n - 1)
    println(map(src, ::factorial)) // => [2, 6, 24]
}

```
#つぎは、リスト２６のfunをmain()の外に出した例
```Kotlin:FuncObj03b.kt  
//リスト２６のfunをmain()の外に出した例
//https://gihyo.jp/dev/serial/01/jvm-kotlin/0003?page=3

//リスト25　リストの各要素を変換して新しいリストを得るmap関数
fun map(ints: List<Int>, f: (Int) -> Int): List<Int> {
  val newList = java.util.ArrayList<Int>()
  for (e in ints) {
    newList.add(f(e))
  }
  return newList
}

// 関数をmain()の外に出す
// 平方を得る関数を各要素に適用(1/2)
fun square(n: Int): Int = n * n

// 階乗を得る関数を各要素に適用(1/2)
fun factorial(n: Int): Int =
    if (n == 1) 1
    else n * factorial(n - 1)

//メインルーチン
fun main(){
    //リスト26　map関数を使う
    // [2, 3, 4]のリストを作る
    val src = listOf(2, 3, 4)

    // 平方を得る関数を各要素に適用(2/2)
    println(map(src, ::square)) // => [4, 9, 16]

    // 階乗を得る関数を各要素に適用(2/2)
    println(map(src, ::factorial)) // => [2, 6, 24]
}

```


##リスト27　関数オブジェクトのリテラル表現（まとめ）
```Kotlin:Closure01.kt
// https://gihyo.jp/dev/serial/01/jvm-kotlin/0003?page=4
//
fun map(ints: List<Int>, f: (Int) -> Int): List<Int> {
  val newList = java.util.ArrayList<Int>()
  for (e in ints) {
    newList.add(f(e))
  }
  return newList
}

//メインルーチン
fun main(){
    // リストを作る
    val list1 = listOf(2, 3, 4)
    val list2 = listOf(5, 6, 7)
    val list3 = listOf(8, 9, 0)
    
    //リスト27　関数オブジェクトのリテラル表現
    // ①
    fun succ(n: Int): Int = n + 1     
    println( map(list1, ::succ) )      //　[3, 4, 5]を出力
    
    // ②
    println( map(list2, fun(n: Int): Int { return n + 2 }) )    //[7, 8, 9]    
    // ③
    println( map(list3, {n: Int -> n + 3}) )    //[11, 12, 3]を出力
}

```
##リスト28　関数リテラル記法
```Closure02.kt
// https://gihyo.jp/dev/serial/01/jvm-kotlin/0003?page=4

// 関数リテラル内で型推論が働く（１）
val foo: (Int) -> Int = {
  n -> n + 1
}

// 引数が1つの場合は暗黙の変数itが使える（２）
val bar: (Int) -> Int = {
  it + 1        // 多分、変数名を考えるのが面倒だから、何でもかんでも変数名をitで代用しようという発想で、この「暗黙」の仕組みを編み出したのだろう。ホントかな?
}

// 複数の文を持つ関数リテラル（３）
val baz: (Int) -> Int = {
  var sum = 0
  for (e in 1..it) {
    sum += e
  }
  sum
}

// 高階関数に渡す特殊な記法（４）
//map(listOf(1, 2, 3)) {it + 1}     //誤記かな？
val a = map(listOf(1, 2, 3) ,{it + 1})

//リスト25(リストの各要素を変換して新しいリストを得るmap関数)を引用
fun map(ints: List<Int>, f: (Int) -> Int): List<Int> {
  val newList = java.util.ArrayList<Int>()
  for (e in ints) {
    newList.add(f(e))
  }
  return newList
}

//メインルーチン
fun main(){
    // （１）「関数リテラル内で推論が働く」の使用例
    println( foo(1) )      //＝＞２
    
    // （２）「引数が１の場合は暗黙の変数ｉｔが使える」使用例
    println( bar(2) )      //＝＞３
    
    // （３）「複数の文を持つ関数リテラル」の使用例
    println( baz(10) )      //＝＞５５
    
    // (4)「高階関数に渡す特殊な表記」の使用例
    println( a )     //＝＞[2, 3, 4]
}
```
[（その２へ続く）](https://qiita.com/guijiu/items/8375e6813881cc7237b2)

＜引用・参考＞
＜原文＞https://gihyo.jp/dev/serial/01/jvm-kotlin/0003
＜リストの使い方＞https://qiita.com/kiririnyo/items/aee905225902d096f7c0
＜末尾再帰の使い方＞　https://sites.google.com/site/memo73737/kotlin/tailrecursive