next up previous contents index
Next: Ce qu'il faut retenir Up: Fonction Previous: Egalité   Contents   Index

Subsections


Fonctions anonymes


Forme lambda

Les fonctions anonymes sont des fonctions sans nom que l'on peut manipuler comme tout autre objet Scheme. Cette notion est directement issue du lambda calcul, la théorie mathématique sous-jacente à Scheme et aux langages fonctionnels.

Le lambda calcul est un formalisme dont la grammaire contient seulement trois définitions, l'application, l'abstraction et la définition. A l'aide de ces seuls éléments, il est possible de définir les nombres entiers et l'arithmétique, les autres nombres, les listes, les vecteurs, ... On retrouve cette capacité à s'auto définir dans les langages comme Scheme ; nous avons vu par exemple comment réécrire quelques fonctions de la bibliothèque standard. Il serait aussi possible de redéfinir les fonctions cons, car et cdr, puis les vecteurs.

L'application du lambda calcul correspond à l'application en Scheme. La définition correspond à la forme spéciale define de Scheme. L'abstraction correspond aux fonctions anonymes de Scheme, autrement appelées formes lambda, ce qui montre clairement l'origine de Scheme.

Une fonction anonyme est définie à l'aide de la forme spéciale :

(lambda (p1 p2 pm) exp1 exp2 expn)

p1, p2, pn sont des symboles représentant les paramètres de la fonction, et exp1, exp2, expn les expressions du corps de la fonction. La forme lambda retourne une fonction anonyme qui peut être manipulée comme tout autre objet Scheme.

Ecrivons par exemple :

Osm> (lambda (a b) (+ a b 10))
  => #procedure

Osm> ((lambda (a b) (+ a b 10)) 5 8)
  => 23

Dans la seconde écriture, nous avons appliqué la fonction anonyme

(lambda (a b) (+ a b 10))

aux arguments 5 et 8, ce qui retourne le résultat 23. Il est possible de définir une variable comme étant une fonction anonyme :

Osm> (define f (lambda (a b) (+ a b 10)))
  => #unspecified

Maintenant, f est une fonction anonyme. Appliquons-la à des arguments :

Osm> (f 4 3)
  => 17

Jusqu'à maintenant, nous croyions que Scheme avait deux formes spéciales define, l'une pour les variables, avec l'écriture :

(define variable valeur)

et l'autre pour les fonctions, avec l'écriture :

(define (fonction p1 p2 ... pm)
  exp1 exp2 ... expn).

Nous venons de constater que la seconde écriture est en réalité une simplification syntaxique de l'écriture :

(define fonction 
        (lambda (p1 p2 ... pm)
          exp1 exp2 ... expn))


Environnement

D'une manière simplifiée, un environnement peut être considéré comme l'ensemble des couples {variable, valeur} vus à un certain endroit du programme. Le contenu de l'environnement change au fur et à mesure de l'exécution du programme.

Considérons l'écriture :

(define f (lambda (a b)
           ; point 2
           (+ a b 10)))
; point 1
(f 1 2)

Lorsque le programme se situe au point 1, il existe un environnement contenant notamment toutes les fonctions standards de Scheme et toutes les fonctions que l'utilisateur a définies comme f. On appelle cet environnement racine l'environnement toplevel.

Lorsque l'on applique f à 1 et 2, l'exécution passe par le point 2. En ce point, l'environnement est constitué du toplevel augmenté des couples {a, 1} et {b, 2}. Lorsque l'on quitte la fonction f, l'environnement redevient le toplevel.

Les formes spéciales que nous avons vues et qui affectent l'environnement sont define, set!, let, do. Nous devons donc maintenant ajouter la forme spéciales lambda.

La puissance de l'abstraction en Scheme, représentée par la forme spéciale lambda, est sa capacité à conserver l'environnement dans lequel elle est définie. Considérons :

Osm> (define f (lambda (a)
                ; point 2
                (lambda (b)
                   ; point 3
                   (+ a b))))
  => #unspecified

La fonction f retourne une fonction anonyme qui additionne les arguments a et b. Essayons :

Osm> f
  => #procedure

Osm> (define x (f 10))
  => #unspecified

Osm> x
  => #procedure

Osm> (x 123)
  => 133

La variable x est associée à une fonction qui ajoute 10 à son argument. Le point remarquable est que la valeur 10 est en fait l'argument qui a servi à construire la fonction associée à x. Cette dernière retient dans un environnement privé le couple {a, 10}. Cette caractéristique est propre aux langages fonctionnels et ne se retrouve pas dans les langages impératifs comme C. Elle permet des écritures extrêmement puissantes, comme la définition d'un formalisme objet basé sur les messages. Nous aurons l'occasion d'utiliser cette possibilité.


next up previous contents index
Next: Ce qu'il faut retenir Up: Fonction Previous: Egalité   Contents   Index
© 1993 to 2001 Erian Concept