Fonctions sans nom
En termes simples, un lambda est une fonction sans nom ou une fonction anonyme. Un petit morceau de code exécutable, qui peut être transmis comme s'il s'agissait d'une variable. En JavaScript:
function () {}; // very simple
Voyons maintenant quelques utilisations de ces lambdas.
Résumé du code passe-partout
Les lambdas peuvent être utilisés pour extraire le code standard. Par exemple des boucles. Nous avons l'habitude d'écrire for
et de while
boucler toute la journée. Mais c'est du code qui ne s'écrit pas. Nous pourrions extraire le code à l'intérieur de la boucle, la partie la plus importante de la boucle, et faire abstraction du reste:
for (var i=0; i<array.length; i++) {
// do what something useful with array[i]
}
en utilisant les forEach
objets de tableau, devient:
array.forEach(function (element, index) {
// do something useful with element
// element is the equivalent of array[i] from above
});
L'abstraction ci-dessus n'est peut-être pas très utile, mais il existe d'autres fonctions d'ordre supérieur, comme forEach
, qui effectuent des tâches beaucoup plus utiles. Par exemple filter
:
var numbers = [1, 2, 3, 4];
var even = [];
// keep all even numbers from above array
for (var i=0; i<numbers.length; i++) {
if (numbers[i] % 2 === 0) {
even.push(numbers[i]);
}
}
alert(even);
// Using the filter method
even = [1, 2, 3, 4].filter(function (number) {
return number % 2 === 0;
});
alert(even);
Délai d'exécution du code
Dans certains environnements, dans lesquels le concept d'événement est disponible, nous pourrions utiliser des lambdas pour répondre aux événements qui peuvent se produire à un moment donné.
window.onload = function () {
alert("Loaded");
};
window.setTimeout(function () {
alert("Code executed after 2 seconds.");
}, 2000);
Cela aurait pu être fait d'autres manières, mais celles-ci sont plutôt verbeuses. Par exemple, en Java, il y a l' Runnable
interface.
Usines de fonctions
Jusqu'à ce point, nous n'utilisions que des lambdas pour ses capacités de sucre syntaxique principalement. Mais il y a des situations où les lambdas peuvent être beaucoup plus utiles. Par exemple, nous pouvons avoir des fonctions qui renvoient des lambdas. Disons que nous avons une fonction dont nous voulons que ses valeurs de retour soient mises en cache.
var users = [];
var getUser = function (name) {
if (! users[name]) {
// expensive operations to get a user. Ajax for example
users[name] = user_from_ajax;
}
return users[name];
};
Plus tard, nous pouvons remarquer que nous avons une fonction similaire:
var photos = [];
var getPhoto = function (name) {
if (! photo[name]) {
// expensive operations to get a user. Ajax for example
photos[name] = photo_from_ajax;
}
return photos[name];
};
Il y a clairement un modèle là-dedans, alors abstenons-le. Utilisons la mémorisation .
/**
* @param {Array} store Data structure in which we cache lambda's return values
* @param {Function} lambda
* @return {Function} A function that caches the result of calling the lambda param
*/
var memoize = function (store, lambda) {
// return a new lambda
return function (name) {
if (! store[name]) {
// Execute the lambda and cache the result
store[name] = lambda(name);
}
return store[name];
};
};
var getUsers = memoize([], function (name) {
// expensive operations to get a user. Ajax for example
});
var getPhotos = memoize([], function (name) {
// expensive operations to get a photo. Ajax for example
});
Comme vous pouvez le voir, en utilisant des lambdas, nous avons pu faire abstraction de la logique de mise en cache / mémorisation. Si pour l'autre exemple il y avait des solutions de contournement, je pense que ce problème particulier est difficilement résolu par d'autres techniques. Nous avons réussi à extraire un code passe-partout important en un seul endroit. Sans oublier que nous nous sommes débarrassés des variables globales users
et photos
.
En regardant votre profil, je vois que vous êtes principalement un utilisateur de Python. Pour le modèle ci-dessus, Python a le concept de décorateurs. Il existe de nombreux exemples sur le net pour les décorateurs de mémorisation . La seule différence est qu'en Python, vous avez très probablement une fonction imbriquée nommée à l' intérieur de cette fonction de décorateur. La raison étant que Python ne prend en charge que les lambdas à expression unique. Mais le concept est le même.
Comme exemple d'utilisation de Python lambda. Le code ci-dessus dans lequel nous avons filtré les nombres pairs peut être représenté en Python comme ceci:
filter(lambda x: x % 2 == 0, [1, 2, 3, 4])
Quoi qu'il en soit, les lambdas ne sont pas si puissants sans fermetures. Les fermetures sont ce qui rend le concept de lambdas si puissant. Dans mon exemple de mémorisation, j'ai utilisé des fermetures pour créer une fermeture autour du store
paramètre. De cette façon, j'ai accès à ce paramètre même après que la memoize
fonction a renvoyé son résultat (un lambda).