En plus des nombreuses bonnes réponses données dans ce fil, le fait que Scala ne nous donne pas de combinateur à point fixe optimisable par appel de queue m'a tellement ennuyé que j'ai décidé d'écrire une macro pour traduire un appel de type combinateur Y en un appel récursif ordinaire et idiomatique (avec optimisation par appel de queue, bien sûr). L'idée est qu'un appel comme
fix[Int,Int]((next) => (y) => ...body...)
est facilement traduisible en
({(input) =>
object next {
def apply(y:Int):Int = ...body...
}
next(input)
})
J'ai mis en place une macro implémentation pour Scala 2.11 (avec des modifications mineures, elle devrait aussi fonctionner avec 2.10) dans ce gist .
Avec cette macro, nous pouvons effectuer des tâches récursives ordinaires de manière anonyme sans craindre un débordement de la pile, par exemple
import asia.blip.ymacro.YMacro._
(y[BigInt,BigInt]((xx) => (y) => if(y==1) 1 else y * xx(y-1)))(2000)
donne
res0: BigInt = 33162750924506332411753933805763240382811...