Skip to main content

Récursivité

Exemple d'introduction

fact(0)=1
fact(n)=n * fact(n-1)

(define (fact n)
(if (zero? n)
1
(* n (fact (sub1 n)))))

Récursivité terminale

Pour rendre une fonction récursive terminale, on déplace le calcul effectuée après l'appel récursif pour le faire avant. Ceci modifie l'ordre des calculs.

Les appels récursifs sont dits terminaux si aucun calcul n'est effectué après leur retour.

L'exemple de la factorielle devient alors

(define (fact-t n r)
(if (zero? n)
r
(fact-t (sub1 n)
(* n r))))

Les valeurs successives de n sont utilisées dans les calculs qui sont effectués avant les appels récursifs. Il est inutile de les conserver dans une pile.

Problème de paramètres

Notre fonction fact-t demande un paramètre supplémentaire qui doit être initialisé à 1. Pour garantir son bon fonctionnement, il faut définir deux fonction, l'une faisant l'appel initial et l'autre le calcul récursif terminal.

(define (factorielle n)
(letrec ((fact-t
(lambda (n r)
(if (zero? n)
r)
(fact-t (sub1 n)
(* n r)))))
(fact-t n 1)))

Continuation fonctionnelle

Une continuation représente le futur d'un calcul, c'est à dire le calcul à faire après le calcul d'une expression. Une continuation est modélisée par une fonction qui s'applique au résultat d'une expression. Elle représente un Goto fonctionnel.

Pour construire la continuation d'un appel récursif, on effectue une abstraction de l'expression contenant le calcul récursif par une application : (k a). La paramètre a de l'application est le résultat de l'appel récursif. La fonction k est la continuation.