Lambdas et closures
Mise à jour le 14 juil. 2022.
Dans la page web Lambda, Martin Fowler décrit les lambdas comme un concept informatique appelés également Closures, Fonctions Anonymes ou Blocs.
Un lambda est un bloc de code pouvant être passé en tant que valeur comme paramètre dans un appel de fonction ; cette valeur peut aussi être exécutée à la demande.
On parle de closure si un lambda fait référence à des variables en dehors du contexte dans lequel il est créé.
Dans ce qui suit, vous trouverez la définition des lambdas et leurs syntaxes dans différents langages de programmation, en commençant par le langage Java.
Le même exemple complet, au travers d'une classe Main
(sauf pour le langage C#, où l'on a la classe Program
), est repris dans les différents langages.
Expressions lambda en Java
En Java, une expression lambda est une expression fournissant une implémentation anonyme d'une interface fonctionnelle, c'est-à-dire d'une interface ayant une unique méthode abstraite (Single Abstract Method).
Une telle interface peut être annotée avec @FunctionalInterface
.
Syntaxe
(paramètres ou aucun paramètre) -> instruction ou { instructions }
Voici un exemple d'expression lambda :
Operation add = (x, y) -> x + y;
Ici, les types des paramètres sont inférés par rapport à l'interface fonctionne Operation
qui est définie ainsi:
1 2 3 4 |
|
Exemple d'utilisation d'une interface fonctionnelle
Poursuivons avec un exemple utilisant l'interface fonctionnelle javafx.event.EventHandler<T extends Event>
de JavaFX ; en réponse au clic sur un bouton dans une scène JavaFX, on utiliserait une classe anonyme ainsi :
1 2 3 4 5 |
|
De manière plus concise et lisible, une expression lambda peut être utilisée à la place de la création de la classe anonyme :
1
|
|
Exemple Main
L'exemple de code ci-dessous, volontairement compact, démontre l'utilisation d'expressions lambda :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
|
Références
Closures Groovy
En langage Groovy, une closure est une instance de la classe groovy.lang.Closure
que l'on peut définir avec la syntaxe donnée ci-dessous.
Une closure peut aussi être utilisée là où dans le code, une expression lambda Java est attendue (voir Closure to type coercion).
De plus, les closures Groovy comprennent un concept de délégation pouvant aider à concevoir des Domain Specific Languages élégants.
Syntaxe
{ [paramètre ou aucun paramètre ->] instruction(s) }
Dans l'exemple de code ci-dessous, la variable add
est une closure :
def add = { long x, long y -> x + y }
Exemple Main
L'exemple de code ci-dessous démontre l'utilisation de closures Groovy, dans lequel on a nul besoin d'interface fonctionnelle comme en Java :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
|
Références
Expressions lambda en Kotlin
En langage Kotlin, une expression lambda est un littéral de type fonction, autrement dit une expression définissant une fonction anonyme ayant un type fonction.
Syntaxe
{ [paramètre ou aucun paramètre ->] instruction(s) }
Dans l'exemple de code ci-dessous, la variable add
est de type (Long, Long) -> Long
:
val add = { x: Long, y: Long -> x + y }
Exemple Main
L'exemple de code ci-dessous démontre l'utilisation des lambdas Kotlin dans notre exemple principal :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
|
Référence
Closures Scala
En langage Scala, une closure est une expression définissant une fonction anonyme ayant donc une signature précise.
Syntaxe
(paramètres ou aucun paramètre) => instruction ou { instructions }
Dans l'exemple de code ci-dessous, la variable add
est de type (Long, Long) => Long
:
val add = (x: Long, y: Long) => x + y
Exemple Main
L'exemple de code ci-dessous démontre l'utilisation des closures en Scala en reprenant l'exemple Main :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
|
Référence
Expressions lambda en C#
En langage C#, une expression lambda est une fonction anonyme que l'on peut utiliser pour créer des types délégués (un délégué est un type encapsulant une méthode) ou des types d'arborescence d'expression.
Les expressions lambda sont particulièrement utiles pour écrire des expressions de requête LINQ.
Syntaxe
(paramètres ou aucun paramètre) => instruction ou { instructions }
Voici un exemple d'expression lambda :
Operation add = (x, y) => x + y;
Ici, les types des paramètres sont inférés par rapport au type délégué Operation
:
delegate long Operation(long x, long y);
Exemple Main
L'exemple de code ci-dessous démontre l'utilisation des closures en C# en reprenant l'exemple principal :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
|
Référence
Fonctions anonymes en Dart
En langage Dart, une fonction anonyme, appelée parfois lambda ou closure, est une instance de la classe Function
que l'on peut définir avec la syntaxe donnée ci-dessous, où codeBlock
représente le corps de la fonction.
Syntaxe
1 2 3 |
|
Dans l'exemple de code ci-dessous, la variable f
est de type Function
:
Function f = (int a, int b) { return a + b; };
Ce qui permet permet d'invoquer f
comme un fonction nommée (par exmple f(1, 2);
).
Si le corps de la fonction peut se réduire à une expression, on peut aussi appliquer l'opérateur fat arrow =>
:
Function f = (int a, int b) => a + b;
Exemple Main
L'exemple de code ci-dessous démontre l'utilisation des fonctions anonymes Dart dans notre exemple principal:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
|