Kotlin(コトリン)の勉強を始めたばっかりです。6年ぐらいJavaをやってて、まぁ、今度のAndroidアプリはKotlinでやってみるか、ということで始めました。
本を読んでいて、次のようなサンプルコードに出会いました。
tailrec private fun gcd(a: Int, b: Int): Int =
if (b == 0) a
else gcd(b, a % b)
tailrecとはなんぞや!!
Kotlin公式サイトで見ます。残念ながら現時点では英語しかないらしい…。
https://kotlinlang.org/docs/reference/functions.html#tail-recursive-functions
簡単に、意訳しますね!
tailrecの修飾子がついた関数は、条件を満たせば、再帰関数をスタックオーバーフローの心配なく使える。
条件は
・その関数自体の呼び出しが、関数の最後である
・try catchブロックの中ではない
だそうです。
以上が、超簡単なtailrecの話でした。以下は、もうちょっと詳しく補足です。
—————————————————-
そもそも、tailrecの日本語が「末尾再帰」なのか「末尾再帰最適化」なのか、よくわかりませんが、再帰関数の、返り値が末尾で再帰する場合、Kotlinの場合はJVMがいい感じに処理してくれるということです。
何がいい感じなのかというと、再帰関数というのはスタックオーバーフローを起こしやすいのです。
自分自身を参照して、ぐるぐる回るので、なかなかストップ条件にいたらない場合、そうなりがちですね。
しかし、 末尾再帰最適化 では、それを普通のwhileループみたいに内部で書き換えてくれるので、スタックオーバーフローの心配がなくなるのです。
すごいー。
「じゃあ、最初からwhileとかで書けばいいじゃん」
という人もいると思います。
♪違う違う~ そうじゃ、そうじゃなーいー
再帰関数はあまりJavaとかでは出てこないですけども、使えると便利なシーンがあります。同じことを何度か繰り返す場合ですね。
その時に、
「ああー この入力値がもしかしてバカでかかったらスタックオーバーフローで止まってしまうのでは…」
と心配をしなくていいのは、素晴らしいことなんです。