Fermeture (informatique)

En informatique, une fermeture est une fonction qui a un environnement qui lui est propre. Dans cet environnement, il existe au moins une variable liée (un nom qui a une valeur, comme un nombre). L'environnement de la fermeture garde les variables liées en mémoire entre les utilisations de la fermeture.

Peter J. Landin a donné à cette idée le nom de fermeture en 1964. Le langage de programmation Scheme a rendu les fermetures populaires après 1975. De nombreux langages de programmation créés après cette date ont été fermés.

Les fonctions anonymes (fonctions sans nom) sont parfois appelées à tort des fermetures. La plupart des langues qui ont des fonctions anonymes ont également des fermetures. Une fonction anonyme est également une fermeture si elle possède un environnement propre avec au moins une variable liée. Une fonction anonyme sans environnement propre n'est pas une fermeture. Une fermeture nommée n'est pas anonyme.

Fermetures et fonctions de premier ordre

Les valeurs peuvent être des chiffres ou d'autres types de données, comme des lettres, ou des structures de données composées de parties plus simples. Dans les règles d'un langage de programmation, les valeurs de première classe sont des valeurs qui peuvent être données à des fonctions, renvoyées par des fonctions et liées à un nom de variable. Les fonctions qui prennent ou renvoient d'autres fonctions sont appelées fonctions d'ordre supérieur. La plupart des langages qui ont des fonctions comme valeurs de première classe ont également des fonctions d'ordre supérieur et des fermetures.

Par exemple, jetez un coup d'œil à la fonction suivante du régime :

Renvoyer une liste de tous les livres dont au moins un exemplaire a été vendu. (définir (seuil de best-sellers) (filtre       (lambda (livre) (>= (seuil de best-sellers)) liste de livres))

Dans cet exemple, l'expression lambda (lambda (livre) (>= seuil de vente de livres)) fait partie de la fonction best-sellers de livres. Lorsque la fonction est exécutée, Scheme doit faire la valeur du lambda. Il le fait en faisant une fermeture avec le code du lambda et une référence à la variable seuil, qui est une variable libre à l'intérieur du lambda. (Une variable libre est un nom qui n'est pas lié à une valeur).

La fonction de filtrage effectue ensuite la fermeture de chaque livre de la liste pour choisir les livres à retourner. Comme la fermeture elle-même a une référence à un seuil, la fermeture peut utiliser cette valeur chaque fois que le filtre exécute la fermeture. La fonction de filtrage elle-même peut être écrite dans un fichier complètement séparé.

Voici le même exemple réécrit en ECMAScript (JavaScript), un autre langage populaire qui supporte les fermetures :

// Retourne une liste de tous les livres ayant au moins un "seuil" d'exemplaires vendus. function bestSellingBooks(threshold) {    return bookList. filter( function(book) { return book. sales >= threshold ; }      ) ; }

ECMAScript utilise ici le mot fonction au lieu de lambda, et la méthode Array.filter à la place de la fonction de filtrage, mais sinon le code fait la même chose de la même manière.

Une fonction peut créer une fermeture et la rendre. L'exemple suivant est une fonction qui renvoie une fonction.

Dans Scheme :

Retourne une fonction qui se rapproche de la dérivée de f ; en utilisant un intervalle de dx, qui doit être suffisamment petit. (définir (dérivée f dx) (lambda (x) (/ (- (f (+ x dx)) (f x)) dx)))

En ECMAScript :

// renvoie une fonction qui se rapproche de la dérivée de f // en utilisant un intervalle de dx, qui doit être suffisamment petit. function derivative(f, dx) { return function(x) { return (f(x + dx) - f(x)) / dx ; } ; }

L'environnement de fermeture conserve les variables liées f et dx après le retour de la fonction de fermeture (dérivée). Dans les langues sans fermeture, ces valeurs seraient perdues après le retour de la fonction de fermeture. Dans les langages avec fermetures, une variable liée doit être conservée en mémoire aussi longtemps qu'une fermeture la possède.

Il n'est pas nécessaire que la fermeture soit faite en utilisant une fonction d'anonymat. Le langage de programmation Python, par exemple, ne supporte que de façon limitée les fonctions anonymes mais dispose de fermetures. Par exemple, l'exemple ECMAScript ci-dessus pourrait être implémenté en Python d'une certaine manière :

# Retourne une fonction qui se rapproche de la dérivée de f # en utilisant un intervalle de dx, qui doit être suffisamment petit. def derivative(f, dx) : def gradient(x) : return (f(x + dx) - f(x)) / dx gradient de retour

Dans cet exemple, la fonction appelée gradient fait une fermeture avec les variables f et dx. La fonction de fermeture extérieure nommée derivative renvoie cette fermeture. Dans ce cas, une fonction anonyme fonctionnerait également.

def derivative(f, dx) : return lambda x : (f(x + dx) - f(x)) / dx

Python doit souvent utiliser des fonctions nommées à la place car ses expressions lambda peuvent ne contenir que d'autres expressions (code qui renvoie une valeur) et non des instructions (code qui a des effets mais pas de valeur). Mais dans d'autres langages, tels que Scheme, tout code renvoie une valeur ; dans Scheme, tout est une expression.

Utilisations des fermetures

Les fermetures ont de nombreux usages :

  • Les concepteurs de bibliothèques logicielles peuvent permettre aux utilisateurs de personnaliser leur comportement en faisant passer les fermetures comme arguments pour les fonctions importantes. Par exemple, une fonction qui trie des valeurs peut accepter un argument de fermeture qui compare les valeurs à trier selon un critère défini par l'utilisateur.
  • Comme les fermetures retardent l'évaluation - c'est-à-dire qu'elles ne "font" rien avant d'être appelées - elles peuvent être utilisées pour définir les structures de contrôle. Par exemple, toutes les structures de contrôle standard de Smalltalk, y compris les branches (if/then/else) et les boucles (while and for), sont définies à l'aide d'objets dont les méthodes acceptent les fermetures. Les utilisateurs peuvent aussi facilement définir leurs propres structures de contrôle.
  • Il est possible de produire des fonctions multiples qui se ferment sur un même environnement, ce qui leur permet de communiquer en privé en modifiant cet environnement (dans des langues qui permettent l'affectation).

Dans le régime

(define foo #f) (define bar #f) (let ((secret-message "none")) (set ! foo (lambda (msg) (set ! secret-message msg))) (set ! bar (lambda () secret-message))) (display (bar)) ; imprime "none" (newline) (foo "meet me by the docks at midnight") (display (bar)) ; imprime "meet me by the docks at midnight" (meet me by the docks at midnight)
  • Les fermetures peuvent être utilisées pour mettre en œuvre des systèmes d'objets.

Note : Certains orateurs appellent "fermeture" toute structure de données qui lie un environnement lexical, mais le terme fait généralement référence à des fonctions spécifiques.

Questions et réponses

Q : Qu'est-ce qu'une fermeture en informatique ?


R : Une fermeture est une fonction qui a son propre environnement.

Q : Que contient l'environnement d'une fermeture ?


R : L'environnement d'une fermeture contient au moins une variable liée.

Q : Qui a donné son nom à l'idée de fermeture ?


R : Peter J. Landin a donné son nom à l'idée de fermeture en 1964.

Q : Quel langage de programmation a rendu les fermetures populaires après 1975 ?


R : Le langage de programmation Scheme a popularisé les fermetures après 1975.

Q : Les fonctions anonymes et les fermetures sont-elles la même chose ?


R : Les fonctions anonymes sont parfois appelées à tort fermetures, mais toutes les fonctions anonymes ne sont pas des fermetures.

Q : Qu'est-ce qui fait d'une fonction anonyme une fermeture ?


R : Une fonction anonyme est une fermeture si elle possède un environnement propre avec au moins une variable liée.

Q : Une fermeture nommée est-elle anonyme ?


R : Non, une fermeture nommée n'est pas anonyme.

AlegsaOnline.com - 2020 / 2023 - License CC3