Kotlinで関数型プログラミング風

最近RubyからElixirに流れて、何でも関数で書きたい子供みたいな厄介な病気になってしまいました。
Kotlin触ってN日目程度なので何か思いつくたびに書き足していこうと思います

## Recrucive

例えばこんなコード

```elixir:Elixir
defmodule String do
  def multiply(text, count) do
    multiply(text, count, "") 
  end

  def multiply(_text, 0, temp) do
    temp
  end

  def multiply(text, count, temp) do
    multiply(text, count - 1, temp <> text)
  end
end

String.multiply("Hello", 10000)
# => "HelloHelloHelloHelloHe........
```

をKotlinで実現してみたい。

```kotlin:Kotlin
fun main(args: Array<String>) {
    println("Hello!".multiply(2))
}

fun String.multiply(i: Int) : String {
    return this.multiple(i - 1, this)
}

tailrec fun String.multiply(i: Int, temp: String) : String {
    if (i <= 0)  return temp
    this.multiply(i - 1, temp + this) 
}

// => "Hello!Hello!"
```

ところがこれ何故か大きすぎる `i` では `java.lang.StackOverflowError` を吐いて死にます。
[公式ドキュメント](https://kotlinlang.org/docs/reference/functions.html#tail-recursive-functions)には

> This allows some algorithms that would normally be written using loops to instead be written using a recursive function, **but without the risk of stack overflow.**

って書いてあるのにな…

Javaにデコンパイルしたりしてみてみた

```java:Javaにデコンパイル
import java.io.PrintStream;
import kotlin.Metadata;
import kotlin.jvm.internal.Intrinsics;
import kotlin.text.StringsKt;
import org.jetbrains.annotations.NotNull;

// ...

public final class Recursive_testKt {
    public static final void main(@NotNull String[] args) {
        Intrinsics.checkParameterIsNotNull((Object)args, (String)"args");
        String string = Recursive_testKt.multiple$default("Hello!", 20000, null, 2, null);
        System.out.println((Object)string);
    }

    @NotNull
    public static final String multiple(@NotNull String $receiver, int i, @NotNull String temp) {
        do {
            Intrinsics.checkParameterIsNotNull((Object)$receiver, (String)"$receiver");
            Intrinsics.checkParameterIsNotNull((Object)temp, (String)"temp");
            if (i == 0) break;
            temp = temp + $receiver;
            --i;
        } while (true);
        return temp;
    }
}
```

`while` になっている…なぜStack Overflowするのか

よく使う `"string".repeat`[(実装)](https://github.com/JetBrains/kotlin/blob/1.1.2/libraries/stdlib/src/kotlin/text/StringsJVM.kt#L409-L429) は `CharSequence` で定義してあって、その内部実装では `StringBuilder` を使っていました。

と思ってこんなふうにしてみたんですが

```kotlin:Kotlin
fun main(args: Array<String>) {
    println("Hello!".multiply(2000))
}

fun CharSequence.multiply(i:Int) : String {
    return StringBuilder(this).multiply(i - 1, StringBuilder()).toString()
}

tailrec fun StringBuilder.multiply(i:Int, temp:StringBuilder) : StringBuilder {
    return if (i <= 0) temp else this.multiply(i - 1, temp.append(this))
}
```

だめでした。頑張って調べよう…

## Pipe Operator (Elixir や F# にあるあれ)
ないです

https://discuss.kotlinlang.org/t/pipe-forward-operator/2098/21
↑を参考にそれっぽくは書けます

```kotlin
fun main(args: Array<String>) {
    "Hello"
     .run { plus("World!") }
     .run { repeat(2) }
     .let { println(it) }
}

// => "HelloWorld!HelloWorld!"
```

~~続ける関数によって `run` `let` `apply` を使い分けなければならないのが面倒ですね~~

###### 2017/5/24 追記
`T.apply` の[実装](https://github.com/JetBrains/kotlin/blob/fee676a2815c6ff9cbe0a20af80d89b55522ad84/libraries/stdlib/src/kotlin/util/Standard.kt#L45-L49)を見てみたところ

```kotlin:apply
/**
 * Calls the specified function [block] with `this` value as its receiver and returns `this` value.
 */
@kotlin.internal.InlineOnly
public inline fun <T> T.apply(block: T.() -> Unit): T { block(); return this }
```

となっていて、 **副作用を起こしてもとのオブジェクトを返す** （構造体でなければ返るものは渡したものと同じ）のでこの場合使えない気がします。つまり破壊的な作業を `apply` すれば良いのですがこの場合そんなことしないと思いますので…
となると `apply` は実質使わないのでは


## リンク
- Kotlin ❤ FP  
  https://blog.plan99.net/kotlin-fp-3bf63a17d64a